Can a template template parameter set other template type parameters by default?

I am trying to do something like the following:

template <typename T> struct A { template <typename U> struct AA { }; }; template <typename V, template <typename> class W = A<V>::AA> // Causes C3202 struct B { }; 

But the Visual Studio 2010 compiler spits out:

error C3202: 'AA': invalid default argument for template parameter '', expected class template

If I replaced B with the following pattern:

 // Replace "T" with "int" template <typename V, template <typename> class W = A<int>::AA> struct B { }; 

The code compiles fine, but that is not what I want. If the original is not legal C ++, is there an alternative that provides a similar interface for users of template "B"?

+8
c ++ templates template-templates
source share
2 answers

Depending on your definition of “looks like,” you can change the definition of template B to

 template <typename V, typename W = A<V>> struct B { }; 

and inside struct B you can access the internal template as

 W::template AA< some_type > 

However, your users would need to provide an AA type wrapped in a class, just like your struct A

You can also reduce compiler compatibility requirements and require MSVC 2013 +.

+1
source share

Your code is not valid C ++ code. See below for a quote.


C ++ 03

14.2 Names of specialized templates [temp.names]

14.2 / 4

When the name of the member template specifier appears after . or -> in a postfix expression or after a nested qualifier name in an identifier with qualification, and a postfix expression or qualified user identifier clearly depends on the template parameter (14.6.2), the name of the member template must have a prefix with the keyword template . Otherwise, it is assumed that the name is called a non-pattern.

14.2 / 5

If the name prefixed with the template keyword is not the name of a member template, the program is poorly formed. [Note: the template keyword cannot be applied to members that are not related to the class template template.] In addition, member template names must not be prefixed with the template keyword if the postfix expression or qualified identifier does not appear within the template . [Note: as with the typename prefix, the template prefix is ​​allowed in cases where this is not strictly necessary; that is, if the expression to the left of -> or . or the naming specifier is independent of the template parameter.]


C ++ 11

14.2 Names of specialized templates [temp.names]

14.2 / 4

When the name of the custom template template appears after . or -> in a postfix expression or after a sub-name specifier in an identifier with qualification, and the postfix-expression object expression is of type -dependent or specified by sub-name-identifier in identified-id refers to the dependent type, but the name is not a member of the current instance (14.6 .2.1), the name of the member template must have a prefix with the keyword template , otherwise it is assumed that the name is called a non-template.

14.2 / 5

The name prefixed with the template keyword must be the template identifier or the name must refer to the class template. [Note. The template keyword may not apply to class template elements without templates. - end note] [Note: as with the typename prefix, the template prefix is ​​allowed in cases where this is not strictly necessary; that is, when the nested name specifier or expression to the left of -> or . independent of the template parameter, or usage is not displayed in the template area. - end note] [Example:

 // ... template <class T> struct B { template <class T2> struct C { }; }; // OK: T::template C names a class template: template <class T, template <class X> class TT = T::template C> struct D { }; D<B<int> > db; 

- end of example]


Standard code

So the correct syntax in this situation is:

 template <typename T> struct A { template <typename U> struct AA { }; }; template <typename V, template <typename> class W = A<V>::template AA> // ^^^^^^^^^^^ struct B { }; 

Unfortunately, VC2010 also does not understand the valid syntax.

+2
source share

All Articles