1

簡単な例:

struct A
{
   A() : i(int()) {}
   const int& i;
};

gccからのエラー:

'A :: i'への一時的なバインドは、コンストラクターが終了するまでのみ持続します

12.2p5からのルール:

コンストラクターのctor-initializer(12.6.2)の参照メンバーへの一時的なバインドは、コンストラクターが終了するまで持続します。

質問

このルールの論理的根拠を知っている人はいますか?参照が死ぬまで一時的に生きることを許可する方が良いように私には思えます。

4

3 に答える 3

2

オブジェクトの存続期間を延長しないことには正当化が必要ではないと思います。反対になります!

一時的なものの存続期間の延長は、それを囲むスコープにのみ延長されます。これは自然で有用です。これは、受信する参照変数の存続期間を厳密に制御しているためです。対照的に、クラスメンバーは実際には「スコープ内」ではありません。これを想像してみてください:

int foo();
struct Bar
{
    Bar(int const &, int const &, int const &) : /* bind */ { }
    int & a, & b, & c;
};

Bar * p = new Bar(foo(), foo(), foo());

foo()一時的なものに意味のある寿命延長を定義することはほぼ不可能です。

代わりに、foo()一時的なものの存続期間が、それが含まれている完全な式の終わりまで延長され、それ以上延長されないというデフォルトの動作があります。

于 2013-01-19T22:41:35.930 に答える
1

コンストラクタ初期化リストのint()はスタック上にあります。

その値が設定されると、int()はスコープ外になり、参照は無効になります。

于 2013-01-19T22:37:24.827 に答える
1

それはどのような記憶に住むでしょうか?

提案どおりに機能するためには、単一の関数呼び出しよりも長く存続する必要があるため、スタックに置くことはできません。Aがどのように割り当てられたかを知る方法がないため、メモリ内の構造体Aの後に置くことはできません。

せいぜい、それは秘密のヒープ割り当てに変えられなければならないでしょう。その場合、デストラクタの実行時に対応するシークレットの割り当て解除が必要になります。コピーコンストラクターと代入演算子にも秘密の振る舞いが必要です。

誰かが実際にそのような方法を考えたことがあるかどうかはわかりません。しかし、個人的には、かなりあいまいな機能には複雑すぎるように思えます。

于 2013-01-20T00:05:33.057 に答える