10

谁能向我解释为什么这两个陈述之间存在差异?

class A{};

const A& a = A();         // correct 

A& b = A();               // wrong

A&它说从临时类型的类型的非常量引用的无效初始化A

为什么在const这里很重要?

4

5 回答 5

14

非常量引用必须用左值初始化。如果你可以用临时变量初始化它们,那么下面会做什么?

int& foo = 5;
foo = 6; // ?!

const引用具有延长裁判寿命的特殊属性,并且由于它们是const,因此您不可能尝试修改不在内存中的内容。例如:

const int& foo = 5;
foo = 6; // not allowed, because foo is const.

请记住,引用实际上必须引用某些东西,而不仅仅是临时变量。例如,以下是有效的:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);
于 2010-02-23T00:46:32.883 回答
3

这方面的术语有点混乱。您可能想进一步研究它们。这是简短的答案:

您正在将一个临时对象(调用类的构造函数的结果)分配给一个变量。临时对象是 R 值。您不能将 R 值分配给非常量引用。

您可以将 R 值分配给 const 引用,尽管允许它的理由非常模糊。

于 2010-02-23T00:46:47.133 回答
1

对于临时/右值,您只能有一个 const 引用。

您可以对非临时/左值进行非常量引用。

A a;
A& b = a;

我相信这样做的原因是为了强调右值是暂时的这一事实,因为能够修改将暂时消失的东西几乎没有价值。

于 2010-02-23T00:43:27.930 回答
1

在 C++ 语言中,将非常量引用附加到右值是非法的,而将 const 引用附加到右值是完全可以的。例如,这是合法的

const int& r = 5;

虽然这不是

int &r = 5; // ERROR

A表达式返回的临时类型的对象A()是一个右值,因此上述规则也适用于您的情况。

于 2010-02-23T00:45:12.837 回答
0

因为标准是这样说的:

§8.5.3.5 ...否则,引用应是对非易失性常量类型的左值引用...

但是,如果你非常想要它,你可以得到它:

#include <iostream>
int main()
{
  const int & cr=5;
  int & r=const_cast<int &>(cr);
  r=6;
  std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64

但是请注意,假定的常量 cr 也不再是 const ,并且您会产生未定义的行为。(§1.9 (4))

正如上面的代码所暗示的,这种差异没有技术原因。相反,设计师对用户将如何处理对临时对象的非常量引用做了噩梦。

于 2016-10-03T15:24:10.087 回答