0
votes

The code:

#include <iostream>

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


int main() { }

Is invalid for CLANG, but valid for GCC. What behavior is actually correct? The Standard wasn't pretty clear about that:

N4296::14.7.1/1 [temp.inst]

Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.

1

1 Answers

5
votes

This is invalid code, because A<1> has incomplete type at the point of usage. Your quote from the standard is not relevant (A<1> cannot be instantinated at the point of usage).

The situation would be different if instead you had

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
};

Moreover, in your original code, what do you think that the value of A<1>::a or A<0>::a should be? Nowhere is there a way to assign a value to it. You claim that gcc compiles this, but what's A<1>:a? garbage? null?


As R Sahu pointed out in the comments, your code also suffers from the fact that you cannot access the member A<1>::a without an object (unless it's a static member).


Regarding the access to members.

In the code referred to by your comment, the member was accessed implicitly as member of the object *this. Thus within class A<1> (or any derived classes), A<1>::a is the same as this->a. But outside you must provide an object.