如何为含不可拷贝不可移动类型的类编写构造函数:成员可选初始化
更简洁的解决方案
可以直接利用std::variant的原位构造能力,配合初始化列表中的立即执行lambda完成Baz的初始化,无需引入智能指针,代码更紧凑:
#include <variant> struct Foo1 { Foo1(int); Foo1(Foo1&&) = delete; }; struct Foo2 { Foo2(int); Foo2(Foo2&&) = delete; }; struct Baz { Baz(Foo1&); Baz(Foo2&); Baz(Baz&&) = delete; }; struct Bar { Bar(int i) : i{i} // 用std::in_place_type原位构造Foo1/Foo2,避免移动/拷贝 , foo{(i == 0) ? std::in_place_type<Foo1> : std::in_place_type<Foo2>, i} // 立即执行lambda获取对应Foo的引用,传给Baz构造 , baz{[this]() -> auto& { return (i == 0) ? std::get<Foo1>(foo) : std::get<Foo2>(foo); }()} {} int i; std::variant<Foo1, Foo2> foo; Baz baz; };
关键细节说明
- 原位构造规避移动限制:通过
std::in_place_type直接在std::variant的内存空间中构造Foo1或Foo2,完全绕开临时对象的移动/拷贝操作,适配类不可移动的约束; - 初始化阶段完成依赖绑定:利用立即执行的lambda在成员初始化阶段就获取到
variant中已构造完成的Foo1/Foo2引用,直接传递给Baz的构造函数,保证初始化顺序合法; - 无额外冗余结构:不需要智能指针、
std::monostate等额外组件,代码逻辑更直接,性能开销更低。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

