【问题标题】:Returning temporary object and binding to const reference [duplicate]返回临时对象并绑定到 const 引用 [重复]
【发布时间】:2012-07-18 14:35:37
【问题描述】:

可能重复:
Does a const reference prolong the life of a temporary?

我的编译器不会抱怨将临时分配给 const 引用:

string foo() {
  return string("123");
};

int main() {
  const string& val = foo();
  printf("%s\n", val.c_str());
  return 0;
}

为什么?我认为从foo 返回的字符串是临时的,并且 val 可以指向生命周期已结束的对象。 C++ 标准是否允许这样做并延长返回对象的生命周期?

【问题讨论】:

  • 是的,只要是 const 引用,临时对象的生命周期就会延长。
  • 这不完全是 2784262 的副本,它(应该)处理引用是类成员的情况。行为不同。
  • @aberaud 这不仅不是重复的,而且我很高兴找到了一个更好的问题。

标签: c++ reference constants


【解决方案1】:

这是一个 C++ 功能。该代码是有效的,并且完全按照它看起来要做的那样做。

通常,临时对象只会持续到它出现的完整表达式的末尾。但是,C++ 特意指定将临时对象绑定到堆栈上的 const 引用会将临时对象的生命周期延长到引用本身的生命周期,从而避免常见的悬空引用错误。在上面的示例中,foo() 返回的临时值一直存在到右花括号为止。

PS:这仅适用于基于堆栈的引用。它不适用于作为对象成员的引用。

全文:GotW #88: A Candidate For the “Most Important const” by Herb Sutter.

【讨论】:

  • 另外,请注意,由于这里没有对字符串进行复制,因此字符串的复制构造函数必须存在并且可以访问。
  • re the P.S,这很重要,上面链接的欺骗 SO 线程对此有很好的说明
  • @xryl669 c++17 Guaranteed copy elision 是否意味着不再需要复制构造函数?引用:```当源对象是临时的```
  • @dashesy 你什么意思?在这种情况下,复制构造函数从不“必要”。在实践中,如果f()return 表达式返回一个未命名的rvalue,RVO 几乎肯定会介入并省略复制构造,而是直接在调用者的接收位置构造返回的对象(多变的)。如果return 表达式返回了一个命名对象,NRVO 可能也会这样做。 C++17 的保证复制省略实现的是在 RVO 的前一种更简单的情况下要求省略。
  • @dashesy 哎呀,我现在明白了。公平的问题。幸运的是,答案很容易找到:stackoverflow.com/a/38043447/2757035 那是是的。它从名称的 保证 部分逻辑上遵循。如果保证复制省略,则不需要可访问的复制或移动构造函数,因为保证不会永远需要。
猜你喜欢
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 2018-08-14
  • 1970-01-01
相关资源
最近更新 更多