常量参考和左值

Const reference and lvalue

本文关键字:参考 常量      更新时间:2023-10-16

我们不能写int& ref = 40,因为我们需要lvalue在右侧。但是我们可以写const int& ref = 40.为什么会这样?40 表示rvalue而不是lvalue

我知道这是一个例外,但为什么呢?

正如Stroustrup所说:

const T&的初始值设定项不必是左值,甚至不必是类型。 T.在这种情况下:

[1] 首先,如有必要,将应用隐式类型转换为 T。

[2] 然后,将结果值放置在 T型。

[3] 最后,这个临时变量用作 初始 化。

因此,当您键入 const int& ref = 40 时,临时 int 变量是在后台创建的,ref 绑定到这个临时变量。

语言中有一条规则,允许将常量左值引用绑定到右值。该规则的主要原因是,如果它不存在,那么您必须提供不同的函数重载才能使用临时函数作为参数:

class T; // defined somewhere
T f();
void g(T const &x);

有了这个规则,你可以做g(f()),没有它,为了能够做到这一点,你必须创建一个不同的g重载来接受右值(这是从语言中甚至没有右值引用的时代!

为什么可能?

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 引用。

您可以将右值绑定到常量引用。该语言保证绑定对象一直存在,直到引用的范围结束,甚至静态调用正确的析构函数。例如,这在 ScopeGuard 实现 (http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758?pgno=2) 中使用,以具有类似虚拟析构函数的行为,而无需为虚拟方法调用付费。