I wanted to create a type that holds a generic type type, that, itself, is a template with one argument. So, if my type is called C, it could be summarized like C<T<U>>.
So, I went for it:
#include <vector>
template <template<typename> class T>
class C
{
// implementation here
};
int main() {
C<std::vector<int>> myType;
}
And I am facing this error:
<source>:10:7: error: template argument for template template parameter must be a class template or type alias template
C<std::vector<int>> myType;
^
1 error generated.
ASM generation compiler returned: 1
What is the correct way of force a template to take a type that itself, is a template that expects other template argument?
You can specialize the class for the case you need and let it undefined otherwise
The above does not work before C++17 because
std::vectorhas a default for its second template type parameter,and before C++17 the part
= std::allocator<T>is ignored, as far as matching thestd::vectortemplate template argument with theTTtemplate template parameter above, sostd::vector<T, std::allocator<T>>never successfully matchC<TT<U>>. (Same thing holds fortemplate<typename, typename = void> struct V {};as it holds forstd::vector, clearly.)This, together with the workaround mentioned in a comment and based on the usage of a variadic template parameter for the template template parameter, is explained in C++ Templates - The Complete Guide 2nd edition, §12.3.4, page 197-198.
As pointed out in another comment, Clang hasn't adopted the C++17 change to the mentioned part of the standard.