英文:
Static templated class inside itself
问题
我们有这样的代码:
template <typename T>
struct A {
static constexpr A a = A{};
};
template <typename T>
struct B {
T a;
};
B<A<int>> b;
GCC 13 对第3行很满意,但是 clang 16 不满意。
<source>:3:21: error: constexpr variable cannot have non-literal type 'const A<int>'
static constexpr A a = A{};
^
<source>:9:4: note: in instantiation of template class 'A<int>' requested here
T a;
^
<source>:12:11: note: in instantiation of template class 'B<A<int>>' requested here
B<A<int>> b;
^
<source>:3:21: note: incomplete type 'const A<int>' is not a literal type
static constexpr A a = A{};
^
<source>:2:8: note: definition of 'A<int>' is not complete until the closing '}'
struct A {
^
1 error generated.
Compiler returned: 1
https://godbolt.org/z/brYMf9har
哪个编译器是正确的?
英文:
We have this kind of code:
template <typename T>
struct A {
static constexpr A a = A{};
};
template <typename T>
struct B {
T a;
};
B<A<int>> b;
GCC 13 seems happy with L.3 but not clang 16.
<source>:3:21: error: constexpr variable cannot have non-literal type 'const A<int>'
static constexpr A a = A{};
^
<source>:9:4: note: in instantiation of template class 'A<int>' requested here
T a;
^
<source>:12:11: note: in instantiation of template class 'B<A<int>>' requested here
B<A<int>> b;
^
<source>:3:21: note: incomplete type 'const A<int>' is not a literal type
static constexpr A a = A{};
^
<source>:2:8: note: definition of 'A<int>' is not complete until the closing '}'
struct A {
^
1 error generated.
Compiler returned: 1
https://godbolt.org/z/brYMf9har
Which compiler is correct?
答案1
得分: 2
Clang是正确的。
不得使用不完整类型定义对象;[basic.def]/5。静态constexpr数据成员隐式地是内联的,因此它的声明就是定义。由于这个定义出现在A
本身的定义内部,所以在这个上下文中,除非上下文是完整类的上下文,否则A
仍然是不完整的。静态数据成员的初始化器不是完整类的上下文;[class.mem.general]/7。
英文:
Clang is correct.
An object shall not be defined with an incomplete type; [basic.def]/5. A static constexpr data member is implicitly inline, so its declaration is a definition. And since this definition occurs inside the definition of A
itself, A
is still incomplete in this context, unless the context is a complete-class context. The initializer of a static data member is not a complete-class context; [class.mem.general]/7.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论