临时变量的生命周期

37
下面的代码可以正常工作,但为什么这是正确的代码?为什么 "c_str()" 指向 foo() 返回的临时对象是有效的?我认为当进入 bar() 时,这个临时对象已经被销毁了,但似乎并非如此。因此,现在我假设 foo() 返回的临时对象将在调用 bar() 后被销毁 - 这是正确的吗?为什么?
std::string foo() {
  std::string out = something...;
  return out;
}

void bar( const char* ccp ) {
  // do something with the string..
}

bar( foo().c_str() );
2个回答

66

当完全评估包含创建该临时对象的rvalue的词法表达式时,该临时对象将被销毁。让我用ASCII艺术形式演示一下:

____________________   full-expression ranges from 'b' to last ')'
bar( foo().c_str() );
     ^^^^^          ^
       |            |
     birth       funeral

9
ASCII艺术中的隐喻插图很形象,我真的很喜欢它们。 - Chubsdad

51

$12.2/3- "临时对象在评估包含它们创建点的(词法)完整表达式(1.9)的最后一步被销毁。即使该评估以抛出异常结束,这也是正确的。"

由foo()返回的临时对象的生命周期延伸到它被创建的完整表达式结束的时候,也就是函数调用'bar'结束的时候。

编辑2:

$1.9/12- "完整表达式是不是另一个表达式的子表达式的表达式。如果语言构造被定义为生成对一个函数的隐式调用,则使用该语言构造被认为是一个表达式,用于本定义目的。"


1
请注意,c_str() 只返回一个临时的 指针。它的生命周期与其指向的数据的生命周期无关。 - jalf
4
c_str()根本不会返回临时对象,而是返回指针类型的rvalue。指针类型的rvalue不是对象,它们没有生命周期。 - Johannes Schaub - litb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接