什么时候临时生命周期扩展在现代C ++中有用?

时间:2018-06-04 04:02:23

标签: c++ lifetime temporary-objects

在C ++中,您可以将函数的返回值(返回值,而不是引用)绑定到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();

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

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

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

1 个答案:

答案 0 :(得分:6)

如果你确切地知道发生了什么,那么将prvalues有意识地延长到像这样的命名堆栈变量是没有用的。这意味着如果您不知道究竟发生了什么,这将非常有用。

说,你是一个模板功能。并且用户应该给你一些具有get成员函数的对象,该函数返回一些符合某些预期行为的类型。问题:get会返回引用还是prvalue?

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

也许get返回对象的引用。或者它可能返回一个prvalue,它是行为的代理对象,就像一个引用。在上面的例子中,它可能有operator=重载,因此您可以为其分配。用户不在乎。

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