为啥定义了移动构造函数而隐式删除了赋值运算符?
Posted
技术标签:
【中文标题】为啥定义了移动构造函数而隐式删除了赋值运算符?【英文标题】:Why is the move constructor defined and the assignment operator implicitly deleted?为什么定义了移动构造函数而隐式删除了赋值运算符? 【发布时间】:2017-05-13 15:25:56 【问题描述】:struct Foo
Foo() = default;
Foo(Foo&&) = default;
;
int main()
Foo a, b;
a = b;
// ^
return 0;
错误:使用已删除的函数 'Foo& Foo::operator=(const Foo&)'
在 g++4.6 -std=c++0x 中没关系。 但是,在 g++6.2 -std=c++11 中是错误的。 为什么?
【问题讨论】:
进一步阅读:"注意:'constexpr Foo& Foo::operator=(const Foo&)' 被隐式声明为已删除,因为 'Foo' 声明了移动构造函数或移动赋值运算符”。那是因为标准是这样说的:***.com/questions/11255027/… 【参考方案1】:答案是因为 C++ 标准是这么说的:
[class.copy]
如果类定义没有显式声明一个副本 构造函数,一个是隐式声明的。如果类定义 声明一个移动构造函数或移动赋值运算符, 隐式声明的复制构造函数被定义为已删除;除此以外, 它被定义为默认值(8.4)。
在你的情况下,你总是可以声明一个默认的复制构造函数:
Foo(const Foo&) = default;
【讨论】:
【参考方案2】:Sam 解释了为什么 GCC 6.2 的行为是正确的。
GCC 4.6 的行为仅仅是由于该版本中不完整的 C++11 支持(正如“实验性”C++0x 开关所证明的那样);直到 4.8 才完全支持 C++11。
【讨论】:
以上是关于为啥定义了移动构造函数而隐式删除了赋值运算符?的主要内容,如果未能解决你的问题,请参考以下文章