临时生命周期延长在现代 C++ 中何时有用?

When is temporary lifetime extension useful in modern C++?

在 C++ 中,您可以将函数的 return 值(return 值,而不是引用)绑定到 const 引用,代码仍然有效,因为此临时文件的生命周期将延长到范围结束。例如

std::string get_string() {
    return "abc";
}


void f() {
    const std::string& str = get_string();
    std::cout << str; // valid, str is not dangling reference.
}

我的问题是,它什么时候有用,例如什么时候像

这样的代码
A get_a();
const A& a = get_a();

比代码更好

A get_a();
A a = get_a();

以什么方式(例如更快、更小的二进制大小等)? Aget_a的实现和调用get_a后的代码应该是什么?

我已经手动测试了几个案例,在每个案例中它似乎都有相同的副本数和移动数。

让我们将这个问题限制在当前的 C++ 标准、编译器的现代版本和启用优化的构建(O2、O3 或其他编译器的等效项)

如果您确切知道发生了什么,故意将 prvalues 的生命周期扩展到命名堆栈变量中是没有用的。这意味着如果您不知道到底发生了什么,它会很有用。

比如说,您在模板函数中。并且用户应该给你一些具有 get 成员函数的对象,该成员函数 return 是某种符合某些预期行为的类型。问题:get return 是引用还是纯右值?

回答:你不在乎。 return 是纯右值还是引用并不重要;重要的是它 return 可以按照您期望的方式进行操作。例如,您可能希望 obj.get() = 10; 起作用。

可能 get return 是对对象的引用。或者它 return 是一个纯右值,它是一个代理对象, 的行为 就像一个引用。在上面的例子中,也许它有一个 operator= 重载,所以你可以给它赋值。你这个用户不在乎。

那么,如果您想将 get return 存储一段(短)时间会怎样?好吧,你不想做 auto x = obj.get();;如果它 return 编辑了一个实际的参考,你会得到一份参考的副本,这可能不是你想要的。所以你 auto &&x = obj.get();。生命周期延长允许它与代理纯右值对象和实际引用一样好地工作。