c ++删除了移动赋值运算符编译问题

gal*_*tte 5 c++ constructor move-semantics c++11

以下代码使用gcc 4.8.0(mingw-w64)失败,其中-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;
}
Run Code Online (Sandbox Code Playgroud)

出错:错误:使用已删除的函数'Param&Param :: operator =(Param &&)'就行了:

param = Param("hop");

如果我删除移动分配删除行,编译好.

应该没有默认的移动赋值运算符,因为有用户定义的复制构造函数,用户定义的复制赋值和析构函数,所以删除它不应该影响编译,为什么它会失败?为什么分配根本不使用复制分配?

cel*_*chk 7

您删除的功能正是您尝试使用的赋值运算符main.通过明确地将其定义为已删除,您声明它并同时说使用它是一个错误.因此,当您尝试从rvalue(Param("hop"))分配时,编译器首先查看是否声明了移动赋值运算符.由于它是并且是最佳匹配,它会尝试使用它,只是为了发现它已被删除.因此错误.

这是另一个不使用特殊功能的机制的例子:

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

int main()
{
  X x;
  short s;
  x.f(s);  // error: f(short) is deleted.
}
Run Code Online (Sandbox Code Playgroud)

删除已删除f(short)将导致编译器选择未删除f(int),因此编译没有错误.

  • 好的我用了错误的单词,现在修好了.但对于赋值,不应该要求移动语义,否则会破坏c ++ 99代码.它应该回归到复制作业.如果我不删除它,则不应该有默认的移动分配. (3认同)
  • 尽管我的答案的*旧*版本,并且根本不适合*当前版本,为什么这个评论仍然会得到赞成? (2认同)