Problem with g ++ pattern

I am porting my C ++ window code (msvc and intel) to Linux (g ++). The code uses a lot of patterns (I like metaprogramming ;-). But I can not 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 the definition of A :: B, class C has invalid template arguments. But on msvc and intel it works well! What is the problem? PS: Sorry, I can’t publish the source code because it is too complex a template. But this example is almost the same and gives the same error in g ++. Thanks.

UPDATE: I found that the problem in the TBA argument for T. g ++ does not like using the second template in the definition.

+6
c ++ templates g ++ porting
source share
1 answer

You need template keyword

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

GCC is correct to give a diagnosis here. This is due to the fact that T cannot be found in the dependent region D<TA> . The value < after it depends on whether T template or not. The standard says that T is not considered a pattern, and therefore T cannot be followed by a list of arguments to the pattern.

template is similar to typename in that it tells the compiler to treat T as a template and that < is the beginning of the argument list anyway. The standard says in paragraphs 14.2/2 and 14.2/4

In order for the template name to be explicitly specified by the template arguments, the name must be known in order to refer to the template.

When then the member template specification appears. or β†’ in the postfix expression or after the nested qualifier name in identified-id, and the postfix expression or qualified box explicitly depends on the template parameter (14.6.2), the member template name must be prefixed with the keyword template. Otherwise, it is assumed that the name is called a non-pattern.

In your case, you have T after the nested qualifier D<TA> , which depends on the template parameter TA . For proper typename-specifier analysis, the constructor D<TA>::T<TBA> must interpret T as the name of a class template that 14.2 forbids.


It is always useful to try and compile with Clang in this thread.

 main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name struct A<TA>::B : C<typename D<TA>::T<TBA> > ^ template 1 error generated. 
+10
source share

All Articles