这个赋值运算符后面的&符号是什么意思?

51

我在阅读这篇有关“五项规则”的精彩回答时,注意到了一些我之前没有看到的内容:

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

在复制赋值运算符和移动赋值运算符的= default前面放置&字符的目的是什么?有没有任何相关资料可以参考?


3
GCC 4.7.1编译错误,我从未听说过在那里放置一个“&”符号。 - chris
5
请阅读对该答案的最后一条评论。 - Some programmer dude
@JoachimPileborg 的确如此,但我不确定该如何理解,所以我宁愿问一下。 - Mihai Todor
1
为了完整起见,请查看什么是“rvalue引用*this”? - Xeo
1
从gcc 4.8.1开始,*this的右值引用被实现。 - Alexander Oh
2个回答

39

这是一个特性的一部分,允许C++11非静态成员函数区分它们是在左值还是右值上被调用。

在上述情况中,默认情况下复制赋值运算符只能在左值上调用。这使用了已经很好地建立起来的左值和右值引用绑定规则;这只是为this建立了它们。

在上述情况中,仅当要复制到的对象可以绑定到非常量左值引用时,才会默认复制赋值运算符。所以这是没有问题的:

C c{};
c = C{};

这不是:

C{} = c;

此处的临时对象无法绑定到左值引用,因此无法调用复制赋值运算符。由于此声明将防止创建通常的复制赋值运算符,所以此语法有效地防止了对临时对象进行复制赋值(或移动赋值)。为了恢复此功能,您需要添加一个 && 版本:

C& operator=(const C&) && = default;
C& operator=(C&&) && = default;

有趣... 这个在任何编译器中实现了吗? - Mihai Todor
1
@MihaiTodor:显然,GCC还没有这个功能(http://gcc.gnu.org/projects/cxx0x.html#rvalue-this),但是Clang从2.9版本开始就有了(http://clang.llvm.org/cxx_status.html)。它通常被称为“rvalue引用for *this”。 - Nicol Bolas
1
在你的帖子中,你一直在提到复制构造函数,但问题是关于复制赋值的。 - Dave S

13

这意味着该函数只能在左值上被调用。因此,由于赋值运算符函数在一个右值对象表达式上被调用,所以这将失败:

C() = x;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接