C2280错误疑问:initial()报错为何initial_2()可正常运行?
问题解答
核心差异:赋值操作 vs 拷贝初始化
这两个函数对应C++里两种完全不同的对象操作逻辑:
initial_2()的正常逻辑:DataTypeA data_a = rd.read_data();这行不是赋值,是拷贝初始化——直接用read_data()返回的临时对象(右值)构造data_a。你已经为DataTypeA定义了移动构造函数DataTypeA(DataTypeA&& rhs),编译器会直接调用这个函数完成对象创建,所以全程无问题。initial()的报错逻辑:data_b = rd.read_data();这里的data_b是类成员,已经在DataContainer构造时通过默认构造完成初始化。现在是对已存在的对象执行赋值操作,这需要依赖DataTypeA的赋值运算符(拷贝赋值或移动赋值)。
为什么赋值会触发C2280错误?
根据C++标准规则:
当你显式定义了移动构造函数后,编译器会自动删除默认生成的拷贝赋值运算符和移动赋值运算符。你的DataTypeA只定义了移动构造,没有提供任何赋值运算符,编译器找不到合法的赋值运算符,只能尝试调用已被删除的默认拷贝赋值,于是触发C2280错误。
解决方法
你注释里的移动赋值运算符只需要修正一个小错误(参数类型误写为TypeB&&,应改为DataTypeA&&),补全后就能让initial()正常运行:
DataTypeA& operator=(DataTypeA&& rhs) noexcept { data = std::move(rhs.data); return *this; }
此时编译器会调用这个移动赋值运算符,把临时对象的资源转移给data_b,完成赋值操作。
内容的提问来源于stack exchange,提问作者stevenhz
相关产品推荐
相关产品推荐

