3

What's wrong with the following sample code? It doesn't compile in GCC. Why?

template <class TA>
struct A
{
    template <class TAB> struct B;
};

template <class TC>
struct C {};


template <class TD>
struct D
{
    template <class TTD> class T {};
};    

template<class TA>
template<class TBA>
struct A<TA>::B : C<typename D<TA>::T<TBA> >
{
    int foo;
};

GCC 4.3.4 output:

error: template argument 1 is invalid
error: expected `{' before ‘>’ token
error: expected unqualified-id before ‘>’ token
Chris Frederick
  • 5,482
  • 3
  • 36
  • 44
Ron Kanga
  • 453
  • 1
  • 4
  • 6
  • Fix your question title to describe the problem, please. – Lightness Races in Orbit Apr 22 '11 at 04:12
  • 2
    I guess a `typename` is missing in some place. Too tired to concentrate, though. I'll leave it to someone else. But I think you should rephrase some parts of your question. Imagine someone finds the question and answers in one year from now. Your frustration will long be gone. The words stay. – 0xC0000022L Apr 22 '11 at 04:13
  • 1
    Nice question ... never saw such complex type template! – iammilind Apr 22 '11 at 05:59

2 Answers2

8

Clang's error message is a bit more helpful:

error: use 'template' keyword to treat 'T' as a dependent template name
struct A<TA>::B : C<typename D<TA>::T<TBA> >
                                    ^
                                    template

For more information consider reading the Stack Overflow C++ FAQ "Where and why do I have to put “template” and “typename” on dependent names?"

Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977
7
struct A<TA>::B : C<typename D<TA>::template T<TBA> >

For a template-name to be explicitly qualified by the template arguments, the name must be known to refer to a template.

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template

T appears after the nested-name-specifier D<TA> which depends on the template-parameter TA. The construct D<TA>::T<TBA> must interpret T as the name of a class template and so the template keyword is mandated by the Standard at that point.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345