在自身内部的静态模板类

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

Static templated class inside itself

问题

我们有这样的代码:

  1. template <typename T>
  2. struct A {
  3. static constexpr A a = A{};
  4. };
  5. template <typename T>
  6. struct B {
  7. T a;
  8. };
  9. B<A<int>> b;

GCC 13 对第3行很满意,但是 clang 16 不满意。

  1. <source>:3:21: error: constexpr variable cannot have non-literal type 'const A<int>'
  2. static constexpr A a = A{};
  3. ^
  4. <source>:9:4: note: in instantiation of template class 'A<int>' requested here
  5. T a;
  6. ^
  7. <source>:12:11: note: in instantiation of template class 'B<A<int>>' requested here
  8. B<A<int>> b;
  9. ^
  10. <source>:3:21: note: incomplete type 'const A<int>' is not a literal type
  11. static constexpr A a = A{};
  12. ^
  13. <source>:2:8: note: definition of 'A<int>' is not complete until the closing '}'
  14. struct A {
  15. ^
  16. 1 error generated.
  17. Compiler returned: 1

https://godbolt.org/z/brYMf9har

哪个编译器是正确的?

英文:

We have this kind of code:

  1. template &lt;typename T&gt;
  2. struct A {
  3. static constexpr A a = A{};
  4. };
  5. template &lt;typename T&gt;
  6. struct B {
  7. T a;
  8. };
  9. B&lt;A&lt;int&gt;&gt; b;

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

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

确定