使用对按值返回的值的const引用

Using a const reference to a returned by value value

本文关键字:const 引用 返回      更新时间:2023-10-16

查看以下示例:

string foo(int i) {
  string a;
  ... Process i to build a ...
  return a;
}
void bar(int j) {
  const string& b = foo(j);
  cout << b;
}

我知道RVO和NRVO,但我认为为了做到这一点,我需要将bar写如下:

void bar(int j) {
  string b = foo(j);
  cout << b;
}

两个版本似乎都有效,我相信性能相同。使用第一个版本(带有const引用)安全吗?

谢谢。

为常量引用指定临时值是完全有效的。临时对象将一直存在,直到引用超出范围。

虽然它在您的示例中没有意义,但此功能通常用于函数参数:

string foo(int i) {
    string a;
    // ...
    return a;
}
void bar(const string& str) {
    // ...
}
void buzz() {
    // We can safely call bar() with the temporary string returned by foo():
    bar(foo(42));
}

在这种简单的情况下是安全的。然而,添加代码很容易,这会使它变得不安全,而且任何了解C++的人都会感到困惑:为什么你需要在这里引用?没有理由这么做,而且通常应该避免这样的代码。

允许const引用绑定到临时的,临时的生存时间将扩展到const引用的生存时间。所以,是的,它是安全的使用。

使用第一个版本(带有const引用)安全吗?

是的。将临时引用绑定到常量引用会将临时引用的生存期延长到引用本身的生存期,这就是声明引用的范围:

void f()
{
   const string& a = foo(10);
   //some work with a
   {
     const string& b = foo(20);
     //some work with b
   } //<----- b gets destroyed here, so the temporary also gets destroyed!
   //some more work with a
} //<----- a gets destroyed here, so the temporary associated 
                                  //with it also gets destroyed!

Herb Sutter在他的文章中详细解释了这一点:

"最重要常数"的候选者

它值得一读。必须读取。