在现代C++中,临时寿命延长何时有用?

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

本文关键字:何时 有用 C++      更新时间:2023-10-16

C++您可以将函数的返回值(返回值,而不是引用(绑定到常量引用,并且代码仍然有效,因为此临时的生存期将延长到作用域结束。例如

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();

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

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

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

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

假设您在模板函数中。用户应该给你一些对象,该对象具有一个get成员函数,该函数返回某种符合某些预期行为的类型。问题:get返回引用还是 prvalue?

答:你不在乎。它是否返回 prvalue 或引用并不重要;重要的是,它返回的内容可以按照您期望的方式进行操纵。因此,例如,您可能希望obj.get() = 10;起作用。

也许get返回对对象的引用。或者,它可能返回一个 prvalue,该 prvalue 是一个充当引用的代理对象。在上述情况下,也许它具有operator=重载,以便您可以分配给它。你用户不在乎。

那么,如果您想在(短(一段时间内存储get返回的内容,会发生什么?好吧,你不想做auto x = obj.get();;如果它返回了实际的引用,您将获得引用的副本,这可能不是您想要的。所以你做auto &&x = obj.get();.生存期延长允许它与代理 prvalue 对象和实际引用一样好。