![](/img/trans.png)
[英]Why does std::array require the size as a template parameter and not as a constructor parameter?
[英]Why does std::stack not use template template parameter?
为什么std::stack
和std::queue
使用类型模板参数而不是模板模板参数作为其底层容器类型?
即为什么stack
声明如下:
template<typename T, typename Container = deque<T>>
class stack;
但不是这样的:
template<typename T, template<typename> class Container = deque>
class stack;
?
因为像std::vector
这样的容器通常有多个模板参数 。 通过不关心它是一个模板,你允许使用每种容器。
怎么会
template<class T, class Allocator = std::allocator<T>> class vector;
适合
template<typename> class Container
就像你在stack
? (提示:它没有!)你需要特殊情况来处理你想要支持的每个数字和类型的模板参数(类型与非类型),这很愚蠢,因为这些通常不会贡献任何比简单更多的信息
typename Container
请注意,要获得例如std::vector
的实际模板参数,您可以使用typedefs std::vector::value_type
和std::vector::allocator_type
,从而无需在实际使用时明确提供这些类型类型(即stack
的Container
)。
简而言之:因为使用模板模板参数比使用类型参数更具限制性*而不提供任何优势。
* 限制性我的意思是你可能需要一个更复杂的东西来获得与“简单”类型参数相同的结果。
为什么没有优势?
你的std::stack
可能有这样的属性:
template <typename T, typename Container>
struct stack {
Container container;
};
如果您通过模板模板参数替换Container
,您为什么会获得?
template <typename T, template <typename...> class Container>
struct stack {
Container<T> container;
};
您只实例化一次Container
,仅用于T
( Container<T>
),因此模板模板参数没有任何优势 。
为什么它更具限制性?
使用模板模板参数,您必须向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还有其他情况不适用于模板模板参数,例如使用模板接受特定顺序中的类型和非类型参数的混合,您可以为其创建通用模板模板参数,甚至使用可变参数模板。
使用模板模板参数会将可用作底层容器的类型限制为公开相同模板签名的类型。 只要这些表单支持预期的接口,它就允许任意类型。
因为它不编译 :
std::deque
不是类型
template <typename T> class std::deque
它的类型
template<class T, class Alloc> class std::deque
这当然是一个更普遍的问题:即使我们要向我们的stack
类模板提供Alloc
模板参数,该类现在只能使用具有两个类型模板参数的容器。 这是一个不合理的限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.