static constexpr member of same type as class being defined
我希望C类有一个静态的C.类型的成员,这是C++ 11中的可能吗?
尝试1:
1 2 3 4 5 | struct Foo { constexpr Foo() {} static constexpr Foo f = Foo(); }; constexpr Foo Foo::f; |
G++4.7.0说:"不完整类型的无效使用"指的是
尝试2:
1 2 3 4 5 | struct Foo { constexpr Foo() {} static constexpr Foo f; }; constexpr Foo Foo::f = Foo(); |
现在的问题是类定义中缺少
尝试3:
1 2 3 4 5 | struct Foo { constexpr Foo() {} static const Foo f; }; constexpr Foo Foo::f = Foo(); |
现在,G++抱怨
如果我正确地解释了标准,那是不可能的。
(§9.4.2/3) [...] A static data member of literal type can be declared in the
class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [...]
综上所述(除了静态数据成员声明中没有关于非文本类型的单独声明外),我认为
1 2 3 4 | struct Foo { constexpr Foo() {} static constexpr Foo f {}; }; |
这与您的尝试1类似,但没有类外部定义。
但是,由于
请注意,本C++-11后文件(N3308)讨论了本标准中当前
我认为GCC拒绝你的第3次尝试是错误的。C++ 11标准中没有规则(或其任何已接受的缺陷报告),它表示变量的重新声明必须是EDCOX1(0)。最接近该规则的标准在[dcl.constexpr](7.1.5)/1中:
If any declaration of a function or function template has
constexpr speci?er, then all its declarations shall contain theconstexpr speci?er.
Clang对
Richard Smith的答案的更新,尝试3现在编译在GCC 4.9和5.1以及Clang 3.4上。
1 2 3 4 5 6 7 8 9 | struct Foo { std::size_t v; constexpr Foo() : v(){} static const Foo f; }; constexpr const Foo Foo::f = Foo(); std::array<int, Foo::f.v> a; |
但是,当foo是一个类模板时,clang 3.4失败,但是gcc 4.9和5.1仍然正常工作:
1 2 3 4 5 6 7 8 9 10 11 | template < class T > struct Foo { T v; constexpr Foo() : v(){} static const Foo f; }; template < class T > constexpr const Foo<T> Foo<T>::f = Foo(); std::array<int, Foo<std::size_t>::f.v> a; // gcc ok, clang complains |
铿锵误差:
1 2 3 | error: non-type template argument is not a constant expression std::array<int, Foo<std::size_t>::f.v> a; ^~~~~~~~~~~~~~~~~~~~~ |