51

我正在阅读这个关于“五规则”的好答案,我注意到一些我不记得以前见过的东西:

class C {
  ...
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  ...
};

放置在复制赋值运算符和移动赋值运算符&前面的字符的目的是什么?= default有人对此有参考吗?

4

2 回答 2

38

它是允许 C++11 非静态成员函数区分它们是在左值还是右值上调用的功能的一部分。

在上述情况下,此处默认的复制赋值运算符只能在左值上调用。这使用了成熟的左值和右值引用绑定规则;这只是建立他们this

在上述情况下,只有当被复制到的对象可以绑定到非 const 左值引用时,才会默认复制赋值运算符。所以这很好:

C c{};
c = C{};

这不是:

C{} = c;

这里的临时值不能绑定到左值引用,因此不能调用复制赋值运算符。并且由于此声明将阻止创建通常的复制赋值运算符,因此此语法有效地阻止了对 temporaries的复制分配(或移动分配) 。为了恢复它,您需要添加一个&&版本:

C& operator=(const C&) && = default;
C& operator=(C&&) && = default;
于 2012-09-06T18:36:44.933 回答
13

这意味着该函数只能在左值上调用。所以这将失败,因为赋值运算符函数是在右值对象表达式上调用的:

C() = x;
于 2012-09-06T18:35:59.373 回答