回答:
安全。const refは、temporaryの寿命を延ばします。スコープはconst refのスコープになります。
一時オブジェクトの存続期間は、const左辺値参照または右辺値参照(C ++ 11以降)にバインドすることによって延長できます。詳細については、 参照の初期化を参照してください。
参照が一時オブジェクトまたはそのサブオブジェクトにバインドされている場合は常に、一時オブジェクトの存続期間が延長され、参照の存続期間と一致しますが、次の例外があります。
- returnステートメント内の関数の戻り値に一時的にバインドされているものは拡張されません。戻り式の終わりですぐに破棄されます。このような関数は常にダングリングリファレンスを返します。
- コンストラクター初期化子リストの参照メンバーに一時的にバインドされるのは、オブジェクトが存在する限りではなく、コンストラクターが終了するまで持続します。(注:このような初期化はDR 1696の時点で正しくありません)。
- 関数呼び出しの参照パラメーターに一時的にバインドされたものは、その関数呼び出しを含む完全な式が終了するまで存在します。関数が完全な式よりも長い参照を返す場合、それはぶら下がり参照になります。
- new-expressionで使用されるイニシャライザの参照への一時的なバインドは、初期化されたオブジェクトではなく、そのnew-expressionを含む完全な式の終わりまで存在します。初期化されたオブジェクトが完全な式よりも長く存続する場合、その参照メンバーはぶら下がり参照になります。
- 初期化子を含む完全な式の終わりまで、リスト初期化構文(中括弧)とは対照的に、直接初期化構文(括弧)を使用して初期化された集合体の参照要素の参照に一時的にバインドされます。
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
一般に、一時オブジェクトの寿命は、「それを渡す」ことによってさらに延長することはできません。一時ファイルがバインドされた参照から初期化された2番目の参照は、その寿命に影響を与えません。
@Konradルドルフが指摘(と上記の最後の段落を参照してください):
「
c.GetSomeVariable()
ローカルオブジェクトへの参照またはそれ自体がオブジェクトの存続期間を延長している参照を返す場合、存続期間の延長は開始されません。」
c.GetSomeVariable()
戻り参照それはいくつかのオブジェクトの生存期間を延長し、それ自体であることをローカルオブジェクトまたは参照に、寿命延長がないではないで蹴る。
ライフタイムエクステンションのおかげで、ここで問題は発生しないはずです。新しく作成されたオブジェクトは、参照が範囲外になるまで存続します。
これは安全です。
[class.temporary]/5
:一時式が完全式の最後とは異なる時点で破棄される3つのコンテキストがあります。[..]
[class.temporary]/6
:3番目のコンテキストは、参照が一時オブジェクトにバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、参照がバインドされているglvalueが次のいずれかによって取得された場合、参照の存続期間中存続します。 :[ここにたくさんあります]
この特定のケースでは安全です。ただし、すべての一時ファイルがconst参照によって安全にキャプチャできるわけではないことに注意してください...たとえば
#include <stdio.h>
struct Foo {
int member;
Foo() : member(0) {
printf("Constructor\n");
}
~Foo() {
printf("Destructor\n");
}
const Foo& method() const {
return *this;
}
};
int main() {
{
const Foo& x = Foo{}; // safe
printf("here!\n");
}
{
const int& y = Foo{}.member; // safe too (special rule for this)
printf("here (2)!\n");
}
{
const Foo& z = Foo{}.method(); // NOT safe
printf("here (3)!\n");
}
return 0;
}
取得された参照z
は、printf
ステートメントに到達する前の完全な式の終わりに一時インスタンスが破棄されるため、安全に使用できません。出力は次のとおりです。
Constructor
here!
Destructor
Constructor
here (2)!
Destructor
Constructor
Destructor
here (3)!