Reference initialization in C++

筅森魡賤 提交于 2019-12-22 04:26:34

问题


Can anybody explain to me why there is a difference between these two statements?

class A{};

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

A& b = A();               // wrong

It says invalid initialization of non-const reference of type A& from a temporary of type A

Why does const matter here?


回答1:


Non-const references must be initialised with l-values. If you could initialise them with temporaries, then what would the following do?

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

const references have the special property that they extend the life of the referee, and since they are const, there is no possibility that you'll try to modify something that doesn't sit in memory. For example:

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

Remember that references actually have to refer to something, not just temporary variables. For example, the following is valid:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);



回答2:


The terminology on this is a little confusing; you may want to research them a bit further. Here's the short answer though:

You are assigning a temporary object (the result of calling the class's constructor) to a variable. A temporary object is an R-value. You can't assign an R-value to a non-const reference.

You are allowed to assign an R-value to a const reference, although the rationale for allowing it is pretty obscure.




回答3:


In C++ language it is illegal to attach a non-const reference to an rvalue, while it is perfectly OK to attach a const reference to an rvalue. For example, this is legal

const int& r = 5;

while this is not

int &r = 5; // ERROR

A temporary object of type A returned by the expression A() is an rvalue, so the above rule applies in your case as well.




回答4:


For a temporary/rvalue, you can only have a const reference.

You can have a non-const reference to a non-temporary/lvalue.

A a;
A& b = a;

I believe the reason why is to reinforce the fact that a rvalue is temporary as there is little value in being able to modify something that is going to disappear momentarily.




回答5:


Because the standard says so:

§8.5.3.5 ... Otherwise, the reference shall be an lvalue reference to a non-volatile const type ...

However, if you want it very much, you can get it:

#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

But be aware that the supposed constant cr is not const any more, too, and you incur undefined behavior. (§1.9 (4))

As suggested by the above code, there is no technical reason for the difference. Rather, the designers had nightmares about what users would do with non-const references to temporaries.



来源:https://stackoverflow.com/questions/2315398/reference-initialization-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!