C ++中的引用初始化

时间:2010-02-23 00:41:40

标签: c++ reference lvalue rvalue const-reference

有人可以向我解释为什么这两个陈述有区别吗?

class A{};

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

A& b = A();               // wrong

它说 从类型为A&

的临时类型初始化A类型的非const引用

为什么const在这里很重要?

5 个答案:

答案 0 :(得分:14)

必须使用l值初始化非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);

答案 1 :(得分:3)

这方面的术语有点令人困惑;你可能想进一步研究它们。这是简短的答案:

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

你可以为一个const引用分配一个R值,虽然允许它的理由非常模糊。

答案 2 :(得分:1)

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

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

A a;
A& b = a;

我认为其原因是为了强化左值是暂时的这一事实,因为能够修改即将消失的东西几乎没有价值。

答案 3 :(得分:1)

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

const int& r = 5;

虽然这不是

int &r = 5; // ERROR

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

答案 4 :(得分:0)

因为标准是这样说的:

  

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

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

#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))

如上述代码所示,差异没有技术原因。更确切地说,设计师们曾经做过噩梦,关于用户对非临时引用临时用户会做些什么。