Possible forms of template template argument in the template instantiation
-
14-06-2021 - |
Question
One of the possible forms of template parameter is a class template. The C++ standard (C++2003) states that an argument for a template template parameter during the template instantiation is an "id-expression". This non-terminal is rather wide. It allows destructors, overloaded operators, etc. For example the following code should compile fine:
template <template <typename x> class T>
struct MyClass
{
T<int> a;
T<double> b;
};
template <typename x> struct Helper
{
~Helper() { }
x operator+(x p) { return(x[1]+p); }
x[4] c;
};
MyClass<Helper> p1;
MyClass<~Helper> p2;
MyClass<Helper::operaror+> p3;
The last 2 lines do not make any sense. But from the standpoint of the grammar they are fine. The grammar is not (and should not) describe the language exactly, but the paragraph 14.3.3, "Template template argument" does not mention any restrictions on the grammar rules in this context.
Can anybody embrace or refute my statements:
- Template template argument can be ONLY an identifier, maybe qualified.
- If point one is true, this is definitely worth mentioning in the standard.
Solution
14.3 [temp.arg] p1
"There are three forms of template-argument, corresponding to the three forms of template-parameter: type, non-type and template. The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list.
The argument ~Helper
does not have the right type for the template template parameter template<typename> class T
, it's not a class template.
14.3.3 [temp.arg.template] p1
A template-argument for a template template-parameter shall be the name of a class template, expressed as id-expression.
~Helper
is not the name of a class template.
That pretty clearly rules out your examples.