作为 const 引用返回的 class 的生命周期

Lifetime of a class returned as const reference

如果我尝试 return 来自函数的字符串文字,我可以制作这两个版本:

std::string get_val()
{
    return "1234";
}

const std::string & get_ref()
{
    return "1234";
}

然而,让我感到困惑的是,我认为你需要一个长期存在的对象,以便拥有一个左值引用(我正在阅读 const std::string & 作为左值引用,也许我错了) .

为什么这行得通? "1234" 在我从函数 return 之后住在哪里?

第二个实现无效。

实际上 return "1234" 创建了一个驻留在堆栈上的临时(右值)字符串对象(就好像它是 return std::string("1234") 一样),一旦它 returns 返回的引用就变成了悬空引用,因为它在堆栈内存中。

最近的编译器会发出如下警告:

https://godbolt.org/z/hWM76n

<source>: In function 'const string& get_ref()':
<source>:5:12: warning: returning reference to temporary [-Wreturn-local-addr]
    5 |     return "1234";
      |            ^~~~~~
std::string get_val()
{
    return "1234";
}

在这种情况下,创建了一个字符串类型的对象,然后调用移动构造函数(通常会说复制,但由于编译器优化,更可能调用移动)以将值存储在目标变量中

const std::string & get_ref()
{
    return "1234";
}

在这里你是return对临时本地对象的引用,所以当字符串的构造函数完成用“1234”构造字符串对象并且return被称为对象时之后被销毁,因为创建的对象在本地范围内是临时的。它应该向您抛出一个错误