临时绑定到引用参数的默认参数的生命周期是多少?

Xeo*_*Xeo 11 c++ lifetime language-lawyer temporary-objects

我认为引用只会将临时工具的生命周期延长到引用本身的生命周期,但下面代码片段的输出似乎是矛盾的:

#include <iostream>

struct X{ ~X(){ std::cout << "Goodbye, cruel world!\n"; } };

X const& f(X const& x = X()){
  std::cout << "Inside f()\n";
  return x;
}

void g(X const& x){
  std::cout << "Inside g()\n";
}

int main(){
  g(f());
}
Run Code Online (Sandbox Code Playgroud)

实例.输出:

Inside f()
Inside g()
Goodbye, cruel world!
Run Code Online (Sandbox Code Playgroud)

因此看起来临时g()被称为......被赋予了什么?

Xeo*_*Xeo 15

该标准在以下特殊情况下处理§12.2 [class.temporary]:

p4有两种情况,临时表在与完整表达结束时不同的点被摧毁.[...]

p5第二个上下文是引用绑定到临时的.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

  • 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止.

该标准还有一个关于全表达式的便利说明,以及关于默认参数的子表达式的评估§1.9 [intro.execution] p11:

[ 注意:对完整表达式的评估可以包括对词汇表的评估,这些子表达式不是词法表达式的全部表达式.例如,计算默认参数(8.3.6)中涉及的子表达式被认为是在调用函数的表达式中创建的,而不是定义默认参数的表达式.- 尾注 ]