函数DataContainer.initial()触发C2280错误。在定义移动赋值运算符之后,它可以工作。但我不清楚为什么在函数initial_2()中它会工作。明显的区别是data_a是局部变量,data_b是类成员。谢谢你的帮助。
#include <vector>
#include <iostream>
class DataTypeA
{
std::vector<double> data;
public:
// default constructor
DataTypeA() {}
// Move constructor
DataTypeA(DataTypeA&& rhs) noexcept :data(std::move(rhs.data))
{
std::cout << __FUNCTION__ << std::endl;
}
//DataTypeA& operator=(TypeB&& rhs) noexcept
//{
// data = (std::move(rhs.data));
// return *this;
//}
DataTypeA(size_t width, size_t height, double default_val) { data.resize(width * height, default_val); }
size_t get_size() const { return data.size(); }
};
class Reader
{
public:
Reader() {}
DataTypeA read_data()
{
DataTypeA rtn(5, 5, 1.2);
return rtn;
}
};
class DataContainer
{
DataTypeA data_b;
public:
DataContainer() {}
void initial()
{
Reader rd;
// this requires the copy or move assignment operator
// Error C2280 'DataTypeA &DataTypeA::operator =(const DataTypeA &)': attempting to reference a deleted function
data_b = rd.read_data();
}
void initial_2()
{
Reader rd;
DataTypeA data_a = rd.read_data();
std::cout << data_a.get_size();
}
};发布于 2022-10-17 12:29:50
在函数initial_2中,您将从现有对象创建一个类型为DataTypeA的新对象,因此可以使用移动构造函数。但是,在initial中,您要将新数据分配给现有对象。为此,需要有赋值操作符。见Difference between the move assignment operator and move constructor?。
发布于 2022-10-17 12:35:49
当您显式声明移动构造函数时,隐式声明的复制和移动赋值操作符被定义为已删除。
来自C++ 17标准(15.8.2复制/移动赋值操作符)
2如果类定义没有显式声明副本赋值操作符,则将隐式声明一个。如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制赋值操作符被定义为已删除的;否则,它被定义为defaulted (11.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不建议使用后一种情况。类X的隐式声明副本赋值运算符将具有以下形式
和
4如果类X的定义没有显式声明移动赋值运算符,则将隐式声明为defaulted当且仅当
(4.1) -X没有用户声明的复制构造函数,
(4.2) - X没有用户声明的移动构造函数,
(4.3) -X没有用户声明的复制赋值操作符,以及
(4.4) -X没有用户声明的析构函数。
在这份声明中
data_b = rd.read_data();必须使用根据引号删除的赋值运算符(根据定义的副本或移动赋值运算符)。
至于这份记录
DataTypeA data_a = rd.read_data();那就是宣言。因此使用了构造函数。
https://stackoverflow.com/questions/74097243
复制相似问题