我们无法写int& ref = 40
,因为我们需要lvalue
在右侧。但我们可以写const int& ref = 40
。为什么这可能? 40是rvalue
而不是lvalue
我知道这是一个例外,但为什么呢?
答案 0 :(得分:13)
正如Stroustrup所说:
const T&的初始化器不必是左值甚至是左右 T.在这种情况下:
[1]首先,如果需要,将应用隐式类型转换为T.
[2]然后,结果值放在一个临时变量中 输入T。
[3]最后,这个临时变量用作的值 初始化程序。
因此,当您键入const int& ref = 40
时,会在幕后创建临时int变量,并将ref绑定到此临时变量。
答案 1 :(得分:11)
语言中有一条规则允许将一个const限值引用绑定到一个rvalue。该规则的主要原因是,如果它不存在,那么你必须提供不同的函数重载才能使用临时值作为参数:
class T; // defined somewhere
T f();
void g(T const &x);
根据该规则,您可以执行g(f())
,如果没有它,您就必须创建一个不同的g
重载,其中包含 rvalue (这是从rvalue-references甚至不在语言中的时候开始的!)
答案 2 :(得分:2)
为什么有可能?
40这里是文字。可以使用文字和临时文件初始化常量引用以延长其生命周期。这可以通过编译器以这种方式完成:
int const& ans = 40;
// transformed:
int __internal_unique_name = 40;
int const& ans = __internal_unique_name;
另一种情况是你有一个功能,例如:
void f( std::string const& s);
,你想用
来调用它f( "something");
此临时变量只能绑定到const引用。
答案 3 :(得分:1)
您可以将rvalue绑定到const引用。该语言保证绑定对象存在,直到引用的范围结束,甚至静态调用正确的析构函数。这是例如在ScopeGuard实现(http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758?pgno=2)中用于具有类似虚拟析构函数的行为,而无需为虚拟方法调用付费。