mip
mip

Reputation: 8733

Typedef evaluation in a class template

Following code compiles with g++, but fails to compile with clang.

struct X;

template <typename T>
struct Traits
{
    typedef typename Traits<T>::Container Container;
};

template <>
struct Traits<X>
{
    typedef std::vector<X *> Container;
};

int main()
{
    Traits<X>::Container container;
    return EXIT_SUCCESS;
}

clang error message:

main.cpp:9:30: error: no type named 'Container' in 'Traits<T>'

Should compiler evaluate the typedef without substituting the template parameter with the actual type? Which compiler is right?

clang: http://coliru.stacked-crooked.com/a/fef7725827074e4f

gcc: http://coliru.stacked-crooked.com/a/79e17031fcabcd83

Upvotes: 4

Views: 257

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275585

template <typename T>
struct Traits {
  typedef typename Traits<T>::Container Container;
};

this is ill formed, no diagnostic required. There is no T such that the above (primary) specialization could result in valid code.

The existence of another specialization makes no difference. The compiler is free to do anything, including giving a spurious error message. It is free to compile it. It is free to generate an error only if you have a variable named foo elsewhere in the program, or if the moon is new. Some if these are poor quality of implementation.

In practice, this means the compiler is free to assume the primary specialization is valid for some type T (i.e., does not have infinite recursion in it), and crap out in relatively unrelated code because it made that assumption.

Upvotes: 5

Related Questions