首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >引用已删除函数的C2280错误尝试

引用已删除函数的C2280错误尝试
EN

Stack Overflow用户
提问于 2022-10-17 12:25:06
回答 2查看 62关注 0票数 1

函数DataContainer.initial()触发C2280错误。在定义移动赋值运算符之后,它可以工作。但我不清楚为什么在函数initial_2()中它会工作。明显的区别是data_a是局部变量,data_b是类成员。谢谢你的帮助。

代码语言:javascript
运行
复制
#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();
    }
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-17 12:29:50

在函数initial_2中,您将从现有对象创建一个类型为DataTypeA的新对象,因此可以使用移动构造函数。但是,在initial中,您要将新数据分配给现有对象。为此,需要有赋值操作符。见Difference between the move assignment operator and move constructor?

票数 2
EN

Stack Overflow用户

发布于 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没有用户声明的析构函数。

在这份声明中

代码语言:javascript
运行
复制
data_b = rd.read_data();

必须使用根据引号删除的赋值运算符(根据定义的副本或移动赋值运算符)。

至于这份记录

代码语言:javascript
运行
复制
DataTypeA data_a = rd.read_data();

那就是宣言。因此使用了构造函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74097243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档