为什么constexpr属性在应用于静态方法时不起作用?

Jer*_*ner 5 c++ 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;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时(使用最新的XCode中的clang ++在MacOS/X下),我得到了这个编译错误:

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()];
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么这是一个错误?为了比较,如果我将Magic()方法移出Test类并使其成为一个独立的函数,它会按预期编译,但我真的不想那样做,因为我想保留Magic()和BLAH如果可能,私有到Test类.

(注意:我不是在这里尝试使用可变长度数组;而是我试图声明一个数组,其大小由编译时函数的计算决定)

Myr*_*ria 3

这是因为类中的函数在类完成之前不会被处理。此规则允许类中定义的函数访问该类中晚于该函数定义的成员。因此,Magic()还没有定义,因此无法在编译时进行评估。

这是正确的行为,尽管各种编译器生成的错误对于理解问题没有帮助。

正式规则位于 [class.member]/6 的 C++ 标准中:

在类说明符}结束时,类被视为完全定义的对象类型 (6.9)(或完整类型)。在类成员规范中,该类在函数体、默认参数、 noexcept-specifiers和默认成员初始值设定项(包括嵌套类中的此类内容)内被视为完整。否则,它在其自己的类成员规范中被视为不完整。