Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ deleted move assignment operator compilation issues

The following code fails with gcc 4.8.0 (mingw-w64) with -O2 -std=c++11 -frtti -fexceptions -mthreads

#include <string>

class Param
{
public:
    Param() : data(new std::string) { }

    Param(const std::string & other) : data(new std::string(other)) { }

    Param(const Param & other) : data(new std::string(*other.data)) { }

    Param & operator=(const Param & other) {
        *data = *other.data; return *this;
    }

    ~Param() {
        delete data;
    }

    Param & operator=(Param &&) = delete;


private:
    std::string * data;
};


int main()
{
    Param param;
    param = Param("hop");


    return 0;
}

With the error : error: use of deleted function 'Param& Param::operator=(Param&&)' On the line :

param = Param("hop");

And compiles well if I remove the move assignment delete line.

There should be no default move assignment operator since there are user defined copy constructors, user defined copy assignment, and destructors, so deleting it should not affect the compilation, why is it failing? And why is the allocation simply not using a copy assignment?

like image 254
galinette Avatar asked Apr 10 '14 22:04

galinette


People also ask

Why is copy assignment operator implicitly deleted?

An implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true: T has a user-declared move constructor; T has a user-declared move assignment operator.

What does a move assignment operator do?

In the C++ programming language, the move assignment operator = is used for transferring a temporary object to an existing object. The move assignment operator, like most C++ operators, can be overloaded. Like the copy assignment operator it is a special member function.

Does move assignment call destructor?

Default move assignment calls destructor, copy assignment doesn't.

How do you write a move assignment operator?

To create a move assignment operator for a C++ class In the move assignment operator, add a conditional statement that performs no operation if you try to assign the object to itself. In the conditional statement, free any resources (such as memory) from the object that is being assigned to.


1 Answers

The function you deleted is exactly the assignment operator you try to use in main. By explicitly defining it as deleted you declare it and at the same time say using it is an error. So when you try to assign from an rvalue (Param("hop")), the compiler first looks whether a move assignment operator was declared. Since it was and is the best match, it tries to use it, just to find that it was deleted. Thus the error.

Here's another example of this mechanism which uses no special functions:

class X
{
  void f(int) {}
  void f(short) = delete;
};

int main()
{
  X x;
  short s;
  x.f(s);  // error: f(short) is deleted.
}

Removing the deleted f(short) will cause the compiler to select the non-deleted f(int) and thus compile without error.

like image 139
celtschk Avatar answered Oct 03 '22 17:10

celtschk