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

时间:2014-04-10 22:29:34

标签: c++ c++11 constructor move-semantics

以下代码使用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;
}

出现错误:错误:使用已删除的功能&#39; Param&amp; PARAM ::运算=(PARAM&安培;&安培;)&#39; 在线:

  

param = Param(&#34; hop&#34;);

如果删除移动分配删除行,则编译好。

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

1 个答案:

答案 0 :(得分: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.
}

删除已删除的f(short)将导致编译器选择未删除的f(int),从而进行编译而不会出错。