当我们尝试实例化模板时,什么应该是正确的行为?

0 c++ templates specialization

代码:

#include <iostream>

template<int N>
struct A
{
    int a = A<1>::a;
};


int main() { }
Run Code Online (Sandbox Code Playgroud)

CLANG无效,但对GCC有效.什么行为实际上是正确的?该标准对此并不十分清楚:

N4296::14.7.1/1 [temp.inst]

除非已经显式实例化了类模板特化(14.7.2)或显式专用(14.7.3),否则在需要完全定义的对象类型或完整性的上下文中引用特化时,将隐式实例化类模板特化.类类型会影响程序的语义.

Wal*_*ter 5

这是无效代码,因为A<1>在使用时具有不完整的类型.您对该标准的引用无关紧要(A<1>无法在使用时立即进行).

如果相反,情况会有所不同

template<int> struct A;
template<> struct A<1> { static int a; };
template<> struct A<2>
{
  int a=A<1>::a;                    // fine: A<1> has complete type
};
Run Code Online (Sandbox Code Playgroud)

此外,在原始的代码,你认为是什么价值A<1>::aA<0>::a应该是什么?没有地方可以为它分配值.你声称gcc汇编了这个,但是什么A<1>:a?垃圾?空值?


正如R Sahu在评论中指出的那样,您的代码也会因为A<1>::a没有对象而无法访问该成员(除非它是static成员).


关于成员的访问.

在您的注释引用的代码中,成员被隐式访问为对象的成员*this.因此,在类A<1>(或任何派生类)中,A<1>::a与...相同this->a.但在外面你必须提供一个对象.