我希望 C 类有一个 C 类型的静态 constexpr 成员。这在 C++11 中可行吗?
尝试 1:
struct Foo {
constexpr Foo() {}
static constexpr Foo f = Foo();
};
constexpr Foo Foo::f;
g++ 4.7.0 说:“不完整类型的无效使用”指的是 Foo()
调用。
尝试 2:
struct Foo {
constexpr Foo() {}
static constexpr Foo f;
};
constexpr Foo Foo::f = Foo();
现在的问题是在类定义中缺少 constexpr
成员 f
的初始化程序。
尝试 3:
struct Foo {
constexpr Foo() {}
static const Foo f;
};
constexpr Foo Foo::f = Foo();
现在 g++ 提示 Foo::f
的重新声明与 constexpr
不同。
最佳答案
如果我正确解释标准,这是不可能的。
(§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. [...]
从上面(以及在静态数据成员声明中没有关于非文字类型的单独声明的事实),我相信静态数据成员 constexpr
必须是一种文字类型(定义见 §3.9/10),并且它的定义必须包含在声明中。使用以下代码可以满足后一个条件:
struct Foo {
constexpr Foo() {}
static constexpr Foo f {};
};
类似于您的尝试 1,但没有类外部定义。
但是,由于 Foo
在静态成员的声明/定义时是不完整的,编译器无法检查它是否是文字类型(定义见 §3.9/10),所以它拒绝代码。
注意有this post-C++-11 document (N3308)讨论了标准中constexpr
当前定义的各种问题,并提出了修改建议。具体来说,“提议的措辞”部分建议对 §3.9/10 进行修订,暗示将不完整类型作为一种文字类型包含在内。如果该修订被接受到标准的 future 版本中,您的问题将得到解决。
关于c++ - 与正在定义的类相同类型的静态 constexpr 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11928089/