次のコード スニペットを考えてみましょう。
<code class="c++">#include <stdio.h> struct P2d { double x, y; P2d(double x, double y) : x(x), y(y) {} ~P2d() { printf("Destructor called\n"); } }; P2d center() { return P2d(10, 10); } int main(int argc, const char *argv[]) { const double& x = center().x; printf("x = %.18g\n", x); return 0; }</code>
When GCC 5.2.0 でコンパイルすると、P2d 一時インスタンスは main で printf 呼び出しに入る前に破棄されます。それにもかかわらず、x の値は保持され、正しく出力されます。つまり、x を P2d テンポラリの x メンバに直接バインドする代わりに、2 番目のテンポラリ double が作成され、メンバの値がコピーされます。
一方、Clang は、P2d テンポラリのライフタイムをライフタイムまで延長します。 x 参照の結果、main の printf の後にデストラクターが呼び出されます。
これにより疑問が生じます: この動作は GCC のバグですか、それとも標準で許可されていますか?
CWG 1651 はこの問題に対処しています:
The resolution of issues 616 and 1213, making the result of a member access or subscript expression applied to a prvalue an xvalue, means that binding a reference to such a subobject of a temporary does not extend the temporary's lifetime. [class.temporary] should be revised to ensure that it does.
現在、[class.temporary]/5 は次のように述べています。「2 番目のコンテキストは、参照が一時的なものにバインドされているときです。 」これは、一時オブジェクトに直接バインドされる参照にのみ適用されると解釈されています。したがって、上記のコード スニペットでは、center().x は (Clang と GCC の両方によって) prvalue として扱われ、[class.temporary]/5 は適用されません。
ただし、GCC と Clang はDR 1651 の解決策、つまり N3918 はまだ実装されていません。この解決策では、「一時式に適用されるメンバー アクセスと添え字式は一時式を生成する」と明示的に述べており、「対応する一時オブジェクト (存在する場合) は参照の存続期間中存続する」と付け加えています。
したがって、 N3918 の文言に基づくと、Clang は意図した動作を実装しているように見えますが、GCC は実装していません。 DR 60297 は、一時オブジェクトのスカラー サブオブジェクトは [dcl.init.ref]/(5.2.1.1) でカバーされていないため、GCC はその有効期間を延長しないと述べています。
要約すると、GCC の現在の動作は次のとおりです。現在の規格の文言によれば正しいですが、この場合、耐用年数の延長が必要となるように規格が改訂される可能性があります。 Clang は、将来予想される動作をすでに実装しています。
以上が## Const 参照を一時オブジェクトのサブパートにバインドすると、その有効期間は延長されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。