14

参照は一時オブジェクトの有効期間を参照自体の有効期間に延長するだけだと思いましたが、次のスニペットの出力は矛盾しているようです:

#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());
}

実例。出力:

Inside f()
Inside g()
Goodbye, cruel world!

だから、呼び出された後に一時的に破棄されたようg()です...何が得られますか?

4

3 に答える 3

19

標準では、次の特殊なケースでこれを処理し§12.2 [class.temporary]ます。

p4 完全式の終わりとは異なる時点で一時変数が破棄される状況が 2 つあります。[...]

p5 2 番目のコンテキストは、参照がテンポラリにバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、次の例外を除き、参照の存続期間中持続します。

  • 関数呼び出し (5.2.2) の参照パラメーターへの一時的なバインドは、呼び出しを含む完全な式が完了するまで持続します

標準には、完全な式と、 のデフォルト パラメータに関する部分式の評価に関する便利なメモもあります§1.9 [intro.execution] p11

[注:完全式の評価には、字句的に完全式の一部ではない部分式の評価を含めることができます。たとえば、デフォルト引数 (8.3.6) の評価に含まれる部分式は、デフォルト引数を定義する式ではなく、関数を呼び出す式で作成されたと見なされます。—終わりのメモ]

于 2012-09-23T17:38:28.977 に答える
1

Interesting, +1. (I do not mean to compete with your nice self answer here). Just a side note for anyone interested. If you want a similar effect but allowing non-const you could use move semantics:

#include <iostream>

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

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

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

int main(){
   g(f());
}

gives

Inside f()
moved Inside g()
Goodbye, cruel world!
Goodbye, cruel world!
于 2012-09-23T18:16:14.437 に答える