与正在定义的类具有相同类型的静态constexpr成员 [英] static constexpr member of same type as class being defined
问题描述
尝试1:
我想要一个类C的静态constexpr成员类型C.这是可能在C ++ 11吗? 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 $
尝试3:
struct Foo {
constexpr Foo(){}
static const Foo f;
};
constexpr Foo Foo :: f = Foo();
现在g ++抱怨重新声明 Foo :: f
不同于 constexpr
。
(§9.4.2/ 3)[...]文字类型的静态数据成员可以在
类定义中使用constexpr说明符声明;如果是,其声明应指定一个括号或初始值化器,其中作为赋值语句的每个初始化子句都是一个常量表达式。 [...]
从上面的内容(以及在静态数据中没有关于非文字类型的单独语句成员声明),我相信, constexpr
的静态数据成员必须是文字类型(如§3.9/ 10定义) ,和,它必须将定义包含在声明中。后面的条件可以通过使用下面的代码来满足:
struct Foo {
constexpr Foo b $ b static constexpr Foo f {};
};
这与您的Attempt 1类似,但没有类外部定义。
但是,因为在声明/定义静态成员时 Foo
不完整,编译器不能检查它是否
请注意,有一个字面类型(如§3.9/ 10中定义),因此它拒绝代码。此后C ++ - 11文档(N3308),其中讨论了 constexpr
,并提出修正建议。具体来说,建议的措辞部分建议修改§3.9/ 10,这意味着包含不完全类型作为一种文字类型。如果该修正案在未来版本的标准中被接受,您的问题将得到解决。
I would like a class C to have a static constexpr member of type C. Is this possible in C++11?
Attempt 1:
struct Foo {
constexpr Foo() {}
static constexpr Foo f = Foo();
};
constexpr Foo Foo::f;
g++ 4.7.0 says: 'invalid use of incomplete type' referring to the Foo()
call.
Attempt 2:
struct Foo {
constexpr Foo() {}
static constexpr Foo f;
};
constexpr Foo Foo::f = Foo();
Now the problem is the lack of an initializer for the constexpr
member f
inside the class definition.
Attempt 3:
struct Foo {
constexpr Foo() {}
static const Foo f;
};
constexpr Foo Foo::f = Foo();
Now g++ complains about a redeclaration of Foo::f
differing in constexpr
.
If I interpret the Standard correctly, it isn't possible.
(§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. [...]
From the above (along with the fact that there is no separate statement about non-literal types in static data member declarations), I believe it follows that a static data member that is constexpr
must be a literal type (as defined in §3.9/10), and it must have its definition included in the declaration. The latter condition could be satisfied by using the following code:
struct Foo {
constexpr Foo() {}
static constexpr Foo f {};
};
which is similar to your Attempt 1, but without the class-external definition.
However, since Foo
is incomplete at the time of declaration/definition of the static member, the compiler can't check whether it is a literal type (as defined in §3.9/10), so it rejects the code.
Note that there is this post-C++-11 document (N3308) which discusses various problems of the current definition of constexpr
in the Standard, and makes suggestions for amendments. Specifically, the "Proposed Wording" section suggests an amendment of §3.9/10 that implies the inclusion of incomplete types as one kind of literal type. If that amendment was to be accepted into a future version of the Standard, your problem would be solved.
这篇关于与正在定义的类具有相同类型的静态constexpr成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!