Are template template template parameters an extension or part of the standard?
-
19-06-2021 - |
Question
I was searching for something else related to template template parameters and happened upon this answer which claims that template template template parameters are not allowed by the standard.
However, the following code compiles in the latest clang (3.2) and the latest GCC (4.8):
template<template<template<typename> class> class T> struct test {};
template<template<typename> class T> struct foo {};
test<foo> bar;
Is this an extension, or is the other answer actually incorrect and it is allowed by the standard? If not, is there any particular reason for the omission?
Solution
In std::vector<int>
the class template std::vector
is passed the type int
as a parameter. In std::get<42>(some_tuple)
, the function template std::get
is passed the value 42
as a parameter. Perhaps unimaginatively the former kind of argument is called a type argument of a template (or template type argument) while the latter kind is a (template) non-type argument.
But templates can also accept another kind of arguments: other templates. For instance template<template<typename> class T> void foo();
declares a function template taking a template as argument, that itself takes a type argument. (As a note, while templates are not types the term 'non-type argument' still does not cover template template arguments. It is reserved for arguments like template<int NonTypeArgument>
.)
Since there is no such thing as a template template in C++ (there are class, function, and alias templates -- but they're collectively simply 'templates' anyway), there is no such thing as a template template template parameter. What you have is a run off the mill template template parameter, where the expected template argument has a template template argument itself. I cannot find a reference in the Standard that forbids this, like the answer you link claims.