临时生命周期延长在现代 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();
以什么方式(例如更快、更小的二进制大小等)? A
、get_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();
。生命周期延长允许它与代理纯右值对象和实际引用一样好地工作。
在 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();
以什么方式(例如更快、更小的二进制大小等)? A
、get_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();
。生命周期延长允许它与代理纯右值对象和实际引用一样好地工作。