如何构造含std::shared_ptr成员的结构体的std::optional实例
核心结论
你不需要手动编写额外的构造函数,本次报错和std::make_optional、类的构造函数都没有关系,是类B的赋值能力缺失导致的。
报错根因
- 你的类B定义了
const std::shared_ptr<A> a成员:const成员初始化后不可修改,因此编译器会自动删除类B的拷贝赋值运算符、移动赋值运算符。 - 代码中
b = std::make_optional<B>(a)是std::optional的移动赋值操作,std::optional的移动赋值运算符要求内部存储的类型支持移动/拷贝赋值,否则该运算符也会被隐式删除,因此触发编译报错。
可行解决方法
根据你的业务场景可任选以下方案:
方案1:直接初始化std::optional,避免赋值操作
不需要先声明空optional再赋值,直接在声明时完成初始化,不会触发optional的赋值运算符,不需要修改类B的定义:
#include <optional> #include <memory> class A { public: A(int v): val{v} {} int val; }; class B { public: B(std::shared_ptr<A>& a): a{a} {} const std::shared_ptr<A> a; }; int main() { std::shared_ptr<A> a = std::make_shared<A>(3); std::optional<B> b = std::make_optional<B>(a); // 直接初始化,无赋值操作 }
方案2:去掉成员变量的const修饰
如果你确实需要先声明空optional再赋值,移除类B成员a的const限定即可让编译器自动生成默认的移动赋值运算符:
class B { public: B(std::shared_ptr<A>& a): a{a} {} std::shared_ptr<A> a; // 移除const修饰 };
方案3:手动实现赋值运算符(不推荐)
如果必须保留成员的const属性且需要支持赋值操作,只能手动实现类B的赋值运算符,该方案违背const成员的语义,不推荐使用。
内容的提问来源于stack exchange,提问作者cjds
相关产品推荐
相关产品推荐

