Today a template template parameter can only be matched by a template class with exactly the same set of template parameters. Default parameters or variadic parameters are ignored.
Example:
template<template<typename> class TPL> class X {
TPL<int> mVar;
};
template<typename A, typename B = int> struct Y {
};
X<Y> fee; // ERROR: Y has too many template parameters, even though one has a default.
template<typename... Ts> struct A {
};
X<A> foo; // ERROR: A has wrong template parameters, although A can be instantiated with one type, just as X will do.
Does anyone know what the rationale is behind this restriction?
One problem this would solve is that today if you want to be able to replace a container which could default to std::vector, the replacement container must also have two template parameters (the second being the allocator).
Another problem it would solve is that you actually have to know that vector has two template parameters and basic_string has three when modelling a template template parameter where they are to be possible candidates.
The other problem is that this rule forbids the designers of the standard library to generalize class templates by adding more template parameters with defaults, as some developer out there may have used the
class template in a template template parameter situation.
This argument was used against me when I suggested that std::array could be made n-dimensional like this:
template<typename T, size_t... dims> class array;
NO NO: That's not backwards compatible, what if someone has done this:
template<template<typename T, size_t> class> class ArrayHolder {};
ArrayHolder<std::array> my_holder; // Breaks with new std::array definition...