在现代C++中,临时寿命延长何时有用?
When is temporary lifetime extension useful in modern C++?
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_a
后A
、get_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 对象和实际引用一样好。
- 何时在引用或唯一指针上使用移动语义
- 何时提供默认参数作为模板参数
- C++-明确何时以及如何调用析构函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 其中降频广播实际上是有用的
- 何时应通过引用传递矢量参数而不是按值传递矢量参数?
- 如果非动态变量被指针引用,何时超出范围?
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 何时定义QT_NO_CONTEXTMENU?
- 何时为派生类初始化 vptr?
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 指针的 C++ 动态数组 - 何时需要使用它?
- 我应该在 C++ 中何时/为什么使用 STATIC?
- 变量的值何时可以在C++中意外更改?
- 调用方如何知道 VARIANT 中何时有十进制?
- 在现代C++中,临时寿命延长何时有用?
- setbuf何时有用(除了NULL值之外)
- 只有编译器的内存屏障(如std::atomic_signal_fence)何时有用
- "already a friend"警告何时有用?