简而言之:因为使用模板模板参数比使用类型参数更严格*而不提供任何优势。
* restrictive 我的意思是你可能需要更复杂的东西来获得与使用“简单”类型参数相同的结果。
为什么没有优势?
您的std::stack 可能具有这样的属性:
template <typename T, typename Container>
struct stack {
Container container;
};
如果用模板模板参数替换Container,为什么会得到?
template <typename T, template <typename...> class Container>
struct stack {
Container<T> container;
};
您只为T (Container<T>) 实例化Container 一次,因此模板模板参数没有优势。
为什么限制更多?
使用模板模板参数,您必须将公开相同签名的模板传递给std::stack,例如:
template <typename T, template <typename> class Container>
struct stack;
stack<int, std::vector> // Error: std::vector takes two template arguments
也许你可以使用可变参数模板:
template <typename T, template <typename... > class Container>
struct stack {
Container<T> container;
};
stack<int, std::vector> // Ok, will use std::vector<int, std::allocator<int>>
但是如果我不想使用标准的std::allocator<int> 怎么办?
template <typename T,
template <typename....> class Container = std::vector,
typename Allocator = std::allocator<T>>
struct stack {
Container<T, Allocator> container;
};
stack<int, std::vector, MyAllocator> // Ok...
这变得有点乱了...如果我想使用自己的容器模板,它接受 3/4/N 个参数怎么办?
template <typename T,
template <typename... > class Container = std::vector,
typename... Args>
struct stack {
Container<T, Args...> container;
};
stack<int, MyTemplate, MyParam1, MyParam2> // Ok...
但是,如果我想使用非模板容器怎么办?
struct foo { };
struct foo_container{ };
stack<foo, foo_container> // Error!
template <typename... >
using foo_container_template = foo_container;
stack<foo, foo_container_template> // Ok...
有了类型参数就不存在这样的问题1:
stack<int>
stack<int, std::vector<int, MyAllocator<int>>
stack<int, MyTemplate<int, MyParam1, MyParam2>>
stack<foo, foo_container>
1 还有其他情况不适用于模板模板参数,例如使用接受特定顺序的类型和非类型参数混合的模板,您可以为此创建泛型template 模板参数,甚至使用可变参数模板。