[英]Why does std::stack not use template template parameter?
Why do std::stack
and std::queue
use type template parameter instead of template template parameter for their underlying container type? 为什么std::stack
和std::queue
使用类型模板参数而不是模板模板参数作为其底层容器类型?
ie why is stack
declared like this: 即为什么stack
声明如下:
template<typename T, typename Container = deque<T>>
class stack;
but not like this: 但不是这样的:
template<typename T, template<typename> class Container = deque>
class stack;
? ?
Because typically containers like std::vector
have more than one template argument . 因为像std::vector
这样的容器通常有多个模板参数 。 By not caring about it being a template, you allow every kind of container to be used. 通过不关心它是一个模板,你允许使用每种容器。
How would 怎么会
template<class T, class Allocator = std::allocator<T>> class vector;
fit onto 适合
template<typename> class Container
as you would have it in your stack
? 就像你在stack
? (Hint: it doesn't!) You'd need special cases for each number and kind of template arguments (type vs. non-type) you'd want to support, which is silly, because these typically don't contribute any more information than a simple (提示:它没有!)你需要特殊情况来处理你想要支持的每个数字和类型的模板参数(类型与非类型),这很愚蠢,因为这些通常不会贡献任何比简单更多的信息
typename Container
Note that to get at the actual template arguments of eg a std::vector
, you have the typedefs std::vector::value_type
and std::vector::allocator_type
, removing the need of having these types available explicitly where you actually use the type (ie the Container
of stack
). 请注意,要获得例如std::vector
的实际模板参数,您可以使用typedefs std::vector::value_type
和std::vector::allocator_type
,从而无需在实际使用时明确提供这些类型类型(即stack
的Container
)。
In short: Because using a template template parameter is more restrictive* than using a type parameter without providing any advantages. 简而言之:因为使用模板模板参数比使用类型参数更具限制性*而不提供任何优势。
* By restrictive I mean that you may need a more complex stuff to obtain the same results than with a "simple" type parameter. * 限制性我的意思是你可能需要一个更复杂的东西来获得与“简单”类型参数相同的结果。
Why is there no advantages? 为什么没有优势?
Your std::stack
probably has an attribute like this: 你的std::stack
可能有这样的属性:
template <typename T, typename Container>
struct stack {
Container container;
};
If you replace Container
, by a template template parameter, why would you obtain? 如果您通过模板模板参数替换Container
,您为什么会获得?
template <typename T, template <typename...> class Container>
struct stack {
Container<T> container;
};
You are instantiating Container
only once and only for T
( Container<T>
), so there is no advantages for a template template parameter. 您只实例化一次Container
,仅用于T
( Container<T>
),因此模板模板参数没有任何优势 。
Why is it more restrictive? 为什么它更具限制性?
With a template template parameter, you have to pass to std::stack
a template which expose the same signature, eg: 使用模板模板参数,您必须向std::stack
传递一个公开相同签名的模板,例如:
template <typename T, template <typename> class Container>
struct stack;
stack<int, std::vector> // Error: std::vector takes two template arguments
Maybe you could use variadic templates: 也许你可以使用可变参数模板:
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>>
But what if I do not want to use the standard 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...
This is becoming a bit messy... What if I want to use my own container templates that takes 3/4/N parameters? 这变得有点乱......如果我想使用自己的容器模板需要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...
But, what if I want to use a non-templated containers? 但是,如果我想使用非模板化容器怎么办?
struct foo { };
struct foo_container{ };
stack<foo, foo_container> // Error!
template <typename... >
using foo_container_template = foo_container;
stack<foo, foo_container_template> // Ok...
With a type parameter there are no such issues 1 : 使用类型参数没有这样的问题1 :
stack<int>
stack<int, std::vector<int, MyAllocator<int>>
stack<int, MyTemplate<int, MyParam1, MyParam2>>
stack<foo, foo_container>
1 There are other cases which do not work with template template parameter such as using templates accepting a mix of type and non-type parameters in specific orders, for which you can create generic template template parameter, even using variadic templates. 1还有其他情况不适用于模板模板参数,例如使用模板接受特定顺序中的类型和非类型参数的混合,您可以为其创建通用模板模板参数,甚至使用可变参数模板。
Using a template template parameter would restrict the types that you could use as the underlying container to those that expose the same template signature. 使用模板模板参数会将可用作底层容器的类型限制为公开相同模板签名的类型。 This form allows arbitrary types as long as they support the expected interface. 只要这些表单支持预期的接口,它就允许任意类型。
Because it doesn't compile : 因为它不编译 :
std::deque
isn't of type std::deque
不是类型
template <typename T> class std::deque
it's of type 它的类型
template<class T, class Alloc> class std::deque
This of course is a more general problem: even if we were to provide the Alloc
template parameter to our stack
class template, the class would now only work with containers that have exactly two type template arguments. 这当然是一个更普遍的问题:即使我们要向我们的stack
类模板提供Alloc
模板参数,该类现在只能使用具有两个类型模板参数的容器。 This is an unreasonable restriction. 这是一个不合理的限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.