在自身内部的静态模板类

huangapple go评论101阅读模式
英文:

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 &lt;typename T&gt;
struct A {
	static constexpr A a = A{};
};


template &lt;typename T&gt;
struct B {
	T a;
};

B&lt;A&lt;int&gt;&gt; b;

GCC 13 seems happy with L.3 but not clang 16.

&lt;source&gt;:3:21: error: constexpr variable cannot have non-literal type &#39;const A&lt;int&gt;&#39;
        static constexpr A a = A{};
                           ^
&lt;source&gt;:9:4: note: in instantiation of template class &#39;A&lt;int&gt;&#39; requested here
        T a;
          ^
&lt;source&gt;:12:11: note: in instantiation of template class &#39;B&lt;A&lt;int&gt;&gt;&#39; requested here
B&lt;A&lt;int&gt;&gt; b;
          ^
&lt;source&gt;:3:21: note: incomplete type &#39;const A&lt;int&gt;&#39; is not a literal type
        static constexpr A a = A{};
                           ^
&lt;source&gt;:2:8: note: definition of &#39;A&lt;int&gt;&#39; is not complete until the closing &#39;}&#39;
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.

huangapple
  • 本文由 发表于 2023年7月27日 17:28:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778327.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定