以下代码使用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;);
如果删除移动分配删除行,则编译好。
应该没有默认的移动赋值运算符,因为有用户定义的复制构造函数,用户定义的复制赋值和析构函数,所以删除它不应该影响编译,为什么它会失败? 为什么分配根本不使用复制分配?
答案 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)
,从而进行编译而不会出错。