谁能向我解释为什么这两个陈述之间存在差异?
class A{};
const A& a = A(); // correct
A& b = A(); // wrong
A&
它说从临时类型的类型的非常量引用的无效初始化A
为什么在const
这里很重要?
谁能向我解释为什么这两个陈述之间存在差异?
class A{};
const A& a = A(); // correct
A& b = A(); // wrong
A&
它说从临时类型的类型的非常量引用的无效初始化A
为什么在const
这里很重要?
非常量引用必须用左值初始化。如果你可以用临时变量初始化它们,那么下面会做什么?
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);
这方面的术语有点混乱。您可能想进一步研究它们。这是简短的答案:
您正在将一个临时对象(调用类的构造函数的结果)分配给一个变量。临时对象是 R 值。您不能将 R 值分配给非常量引用。
您可以将 R 值分配给 const 引用,尽管允许它的理由非常模糊。
对于临时/右值,您只能有一个 const 引用。
您可以对非临时/左值进行非常量引用。
A a;
A& b = a;
我相信这样做的原因是为了强调右值是暂时的这一事实,因为能够修改将暂时消失的东西几乎没有价值。
在 C++ 语言中,将非常量引用附加到右值是非法的,而将 const 引用附加到右值是完全可以的。例如,这是合法的
const int& r = 5;
虽然这不是
int &r = 5; // ERROR
A
表达式返回的临时类型的对象A()
是一个右值,因此上述规则也适用于您的情况。
因为标准是这样说的:
§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))
正如上面的代码所暗示的,这种差异没有技术原因。相反,设计师对用户将如何处理对临时对象的非常量引用做了噩梦。