2017-12-07 4 views
5

はこの些細なテストコードを考えてみましょう:静的メソッドに適用するとconstexpr属性が機能しないのはなぜですか?

class Test 
{ 
public: 
    Test() {/* empty */} 

private: 
    enum {BLAH = 42}; 

    static constexpr int Magic() {return BLAH*4;} 

    float f[Magic()]; 
}; 

int main(int argc, char ** argv) 
{ 
    Test t; 
    return 0; 
} 

私は(MacOSの下/ X最新のXCodeから打ち鳴らす++を使用して)、それをコンパイルしようとすると、私はこのコンパイラエラーを取得:

Jeremys-Mac-Pro:~ jaf$ clang++ -std=c++11 ./test.cpp 
./test.cpp:11:14: error: fields must have a constant size: 'variable length 
     array in structure' extension will never be supported 
     float f[Magic()]; 

誰が説明することができますなぜこれはエラーですか?比較のため、Magic()メソッドをTestクラスから移動してフリースタンディング関数にすると、期待通りにコンパイルされますが、Magic()とBLAH可能であれば、Testクラス専用です。

(注:私はここでは可変長配列を使用しようとしていないよ。むしろ、私はそのサイズがコンパイル時に関数の計算によって決定された配列を宣言しようとしている)

答えて

3

それだからクラス内の関数は、クラスが完了するまで処理されません。このルールは、クラス内で定義された関数が、そのクラスの後にその関数よりも定義されたそのクラスのメンバーにアクセスできるようにします。その結果、Magic()にはまだ定義がないため、コンパイル時に評価することはできません。

これは正しい動作ですが、さまざまなコンパイラが生成するエラーは問題の理解に役立ちません。

正式なルールは[class.member]/6でC++標準である:

A class is considered a completely-defined object type (6.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

関連する問題