1

The function DataContainer.initial() triggers a C2280 error. After defining a move assignment operator it works. But I am not clear why in function initial_2() it works. The obvious difference is that data_a is a local variable and data_b is a class member. Thanks for helping.

#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();
    }
};
stevenhz
  • 57
  • 6
  • Despite the similar syntax the two lines do different things. `DataTypeA data_a = rd.read_data();` is an initialization, `data_b = rd.read_data();` is an assignment – UnholySheep Oct 17 '22 at 12:28
  • 1
    read the full error message. The error number "C2280" is rather useless, but the complete error message should contain valuable information. For example gcc says all you need to know https://godbolt.org/z/x7bvGocez – 463035818_is_not_an_ai Oct 17 '22 at 12:29
  • Dupe: [C++ Compiler Error C2280 "attempting to reference a deleted function"](https://stackoverflow.com/questions/31264984/c-compiler-error-c2280-attempting-to-reference-a-deleted-function-in-visual). Refer to [how to ask](https://stackoverflow.com/help/how-to-ask) where the first step is to *"search and then research"* and you'll find plenty of related SO posts for this. – Jason Oct 17 '22 at 12:37

2 Answers2

2

In the function initial_2, you are creating a new object of type DataTypeA from an existing object, so you can use the move constructor. However, in initial, you are assigning new data to an existing object. For this, you need to have the assignment operator. See Difference between the move assignment operator and move constructor?.

pigrammer
  • 2,603
  • 1
  • 11
  • 24
0

As you explicitly declared the move constructor then the implicitly declared copy and move assignment operators defined as deleted.

From the C++ 17 Standard (15.8.2 Copy/move assignment operator)

2 If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor. The implicitly-declared copy assignment operator for a class X will have the form

and

4 If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if

(4.1) — X does not have a user-declared copy constructor,

(4.2) — X does not have a user-declared move constructor,

(4.3) — X does not have a user-declared copy assignment operator, and

(4.4) — X does not have a user-declared destructor.

And in this statement

data_b = rd.read_data();

there must be used an assignment operator (either the copy or move assignment operator depending on which is defined) that is according to the quotes is deleted.

As for this record

DataTypeA data_a = rd.read_data();

then it is a declaration. So there is used a constructor.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • You could have closed this as duplicate instead of repeating and copy pasting the same content from one answer to another. There are many many duplicates for this. – Alex Oct 17 '22 at 12:44
  • @Ronald this isnt copied from another answer. If it is you should provide a link. Retelling things that are already available elsewhere and a plain copy without proper reference, which would be plagiarism, are two totally different stories. – 463035818_is_not_an_ai Oct 17 '22 at 14:23