7

非常に簡単な質問です。これは有効なC++11ですか?

struct Foo {
    int bar = 1;
    int baz = bar;
};

GCC(4.7.2)とClang(3.1)はどちらも、衒学的な設定でそれを受け入れます。

-std = c ++ 11 -Wall -W -pedantic

Intel C ++(13.0.1.117)はそうではありません。それはと吠えint baz = bar;ます:

エラー:非静的メンバー参照は特定のオブジェクトに関連している必要があります

誰が正しいですか?

不思議に思うかもしれませんが、私はこれを次のようなコードに使用します。このコードでは、最後の行をコンストラクターに移動するのではなく、初期化コードを近づけます。

uint8_t colorR = -1;
uint8_t colorG = -1;
uint8_t colorB = -1;
uint8_t colorA = -1;
GLubyte RGBAVec[4] = {colorR, colorG, colorB, colorA};
4

1 に答える 1

3

5.1p12クラスの非静的データメンバーまたは非静的メンバー関数を示すid式は、次の場合にのみ使用できます

  • オブジェクト式がメンバーのクラスまたはそのクラスから派生したクラスを参照するクラスメンバーアクセス(5.2.5)の一部として、または
  • メンバーへのポインタを形成する(5.3.1)、または
  • そのクラスまたはそのクラスから派生したクラス(12.6.2)のコンストラクターのmem-initializerで、または
  • そのクラスまたはそのクラスから派生したクラス(12.6.2)の非静的データメンバーのブレースまたはイコールイニシャライザでまたは
  • そのid式が非静的データメンバーを示し、未評価のオペランドに表示される場合。

そうです、これ:

struct Foo {
  int bar = 1;
  int baz = bar;
};

有効なC++11です。

ただし、次の理由から順序に注意してください。

12.6.2p10非委任コンストラクターでは、初期化は次の順序で進行します。

  • まず、最も派生したクラス(1.8)のコンストラクターの場合のみ、仮想基本クラスは、基本クラスの有向非巡回グラフの深さ優先の左から右へのトラバースに表示される順序で初期化されます。 to-right」は、派生クラスbase-specifier-list内の基本クラスの出現順序です。
  • 次に、直接基本クラスは、(mem-initializersの順序に関係なく)base-specifier-listに表示される宣言の順序で初期化されます。
  • 次に、非静的データメンバーは、クラス定義で宣言された順序で初期化されます (ここでも、mem-initializersの順序に関係なく)。
  • 最後に、コンストラクター本体の複合ステートメントが実行されます

したがって、非静的データメンバー初期化子の提案(問題3)で指定されているように:

3番目の問題は、クラススコープルックアップがコンパイル時エラーを実行時エラーに変える可能性があることです。

struct S {
    int i = j; // ill-formed without forward lookup, undefined behavior with
    int j = 3;
};

(コンパイラーによってキャッチされない限り、iは未定義のjの値で初期化される可能性があります。)

于 2012-12-14T16:44:07.283 に答える