void foo(const Object & o = Object()) {
return;
}
上記の関数では、いつ ~Object が呼び出されることになっていますか? 関数が終了するとき、または呼び出しサイトを囲むブロックの最後にあるとき?
void foo(const Object & o = Object()) {
return;
}
上記の関数では、いつ ~Object が呼び出されることになっていますか? 関数が終了するとき、または呼び出しサイトを囲むブロックの最後にあるとき?
デフォルトの引数は、関数呼び出しを含む完全な式の最後で破棄されます。
デビッドが言ったことを少し詳しく説明すると、標準はセクション12.2 [class.temporary]で次のように述べています。
完全式の終わりとは異なる時点で一時変数が破棄される状況が 2 つあります。[...] 2 番目のコンテキストは、参照が一時的にバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、次の例外を除き、参照の存続期間中持続します。
- ...
- 関数呼び出し (5.2.2) の参照パラメーターへの一時的なバインドは、呼び出しを含む完全な式が完了するまで持続します。
- ...
したがって、関数が終了したときや呼び出しを含むブロックが終了したときではなく、関数呼び出しを含む完全なステートメントの最後で破棄されます (単に、関数呼び出しの後の最初のセミコロンで、呼び出しコンテキストで)。
編集:だから、私たちが得たとしましょう:
int foo(const Object & o = Object());
some_stuff();
std::cout << (foo() + 7);
other_stuff();
これは、次のものとほぼ同等である必要があります (概念的なスコープ ブロックに注意してください)。
some_stuff();
{
Object o; // create temprorary
int i = foo(o); // and use it
int j = i + 7; // do other things
std::cout << j; // while o still alive
} // finally destroy o
other_stuff();
編集:マイケルがコメントで指摘したように、この「ステートメント/セミコロン」 -私が与えた類推は、 「完全式」という用語の単純化であり、彼の例のように少し異なる場合があります:
if(foo()) bar();
が呼び出される前に一時的なものを破壊するためbar
、式ステートメントとは異なります。
foo() ? bar() : 0;
ただし、完全な式がステートメント (複数の完全な式で構成される可能性がある) と必ずしも同じではない場合でも、 "セミコロン"の類似性はしばしば適切です。
このコードはコンパイルされるべきではないと思います。でない限り、参照を一時的にバインドすることはできませんconst
。それがconst
一時的なものである場合は、関数式の最後まで生き続ける必要があります。その中で定義されたローカル変数とまったく同じです。