如何向STL容器元素构造函数传递引用参数?
问题分析与解决方案
你的代码编译失败核心原因有两点:
S的默认构造函数本身存在隐患——它试图初始化引用成员_c但未绑定到任何有效对象,属于非法的未定义行为;std::array是聚合类型,当你用{c}初始化时,第一个元素会调用S(c)构造,但剩余9个元素会尝试触发默认构造的S(),这直接导致编译报错。
下面提供几种无需使用指针的解决思路:
方法1:显式初始化所有元素(适合小容量数组)
直接删掉S的默认构造函数(强制必须通过引用初始化),然后在std::array初始化时为每个元素传入c:
struct C {}; struct S { // 移除默认构造,确保引用成员必然绑定有效对象 S(const C& c) : _c(c) {} const C& _c; }; int main() { C c; // 为array的10个元素逐一传入c的引用 std::array<S, 10> arr{ c, c, c, c, c, c, c, c, c, c }; return 0; }
这种方式简单直接,但数组容量较大时写起来繁琐。
方法2:用std::reference_wrapper替代原生引用
std::reference_wrapper是标准库专门为解决「容器无法存储原生引用」设计的工具,它是可复制、可赋值的引用包装器,完美适配STL容器要求:
#include <functional> #include <array> struct C {}; struct S { S() = default; S(const C& c) : _c(c) {} std::reference_wrapper<const C> _c; }; int main() { C c; std::array<S, 10> arr; // 批量将所有元素绑定到c arr.fill(S(c)); // 也可以用初始化列表+循环赋值的方式 // std::array<S, 10> arr{S(c)}; // for(auto& elem : arr) elem._c = c; // 使用时可通过get()获取原生引用,或隐式转换 const C& ref = arr[0]._c; return 0; }
方法3:用算法批量初始化(适合大容量数组)
借助std::generate算法批量构造每个元素,避免手动写重复的初始化代码:
#include <array> #include <algorithm> struct C {}; struct S { S(const C& c) : _c(c) {} const C& _c; }; int main() { C c; std::array<S, 10> arr; // 用lambda生成每个绑定到c的S对象 std::generate(arr.begin(), arr.end(), [&c](){ return S(c); }); return 0; }
注:这里依赖编译器自动生成的移动构造函数,S的引用成员移动后仍会绑定到原对象,可正常工作。
总结
不建议保留S的默认构造函数,未绑定的引用成员是严重的未定义行为隐患。优先推荐使用std::reference_wrapper,它是标准库提供的优雅解决方案,既避免了指针,又能满足STL容器的使用要求。
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

