foo は初期化されていないため、初期化子リストを使用して、bar の前に少なくとも 1 のサイズで foo を初期化できます。これは c++98 でも有効です。
struct C{
std::vector<int> foo;
const int &bar;
C();
};
C::C() : foo(1) // initialize foo with size 1
, bar(foo[0]) {
foo[0]=5; // this is guarateed to be exception safe
}
ただし、イニシャライザ リストの順序に注意する必要があります。構造体/クラスでの宣言の順序で並べられます。ここを参照
ISO/IEC 14882:2003(E) セクション 12.6.2 によると:
初期化は次の順序で進行します。
- 最初に、以下で説明するように、最も派生したクラスのコンストラクターに対してのみ、仮想基底クラスは、基底クラスの有向非巡回グラフの深さ優先の左から右への走査に現れる順序で初期化されます。 -to-right」は、派生クラス base-specifier-list 内の基本クラス名の出現順序です。
- 次に、直接基底クラスは、base-specifier-list に表示される宣言順に初期化されます (mem-initializer の順序に関係なく)。
- 次に、非静的データ メンバーは、クラス定義で宣言された順序で初期化されます (これも mem-initializer の順序に関係なく)。
- 最後に、コンストラクターの本体が実行されます。
編集:
Kerrek SBのコメントのおかげで、ベクターを使用できません。何かをプッシュしている間、foo はサイズ変更 (再割り当て) され、bar は正しい参照を失います。std::deque
ベクトルを使用するか、決して渡されない特定のサイズに初期化することができます。