I’m porting my c++ windows code (msvc & intel) to Linux (g++). The code uses lots of templates (I like metaprogramming ;-). But I can’t compile this code:
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;
};
g++ tells me that in definition of A::B, C class has invalid template arguments. But on msvc and intel it works well! What’s the problem here?
PS: Sorry, I can’t post the original code, because it’s too template-complicated. But this example is virtually the same and gives the same error on g++.
Thank you.
UPDATE: I’ve found the problem is in TBA argument of T. g++ doensn’t like usage of second template in the definition.
You need the
templatekeywordGCC is correct to give a diagnostic here. This is because
Tcannot be looked up in the dependent scopeD<TA>. The meaning of the<after it depends on whetherTis a template or not. The Standard says thatTshall be assumed to be not a template and thusTcannot be followed by a template argument list.templateis liketypenamein that it tells the compiler to treatTas a template and that the<is the start of an argument list in any case. The Standard says in paragraphs14.2/2and14.2/4In your case, you have
Tappear after the nested-name-specifierD<TA>which depends on the template-parameterTA. For the typename-specifier to parse correctly, the constructD<TA>::T<TBA>must interpretTas the name of a class template, which14.2forbids.On that topic, it’s always a good idea to try and compile with Clang