简体   繁体   English

为什么std :: stack不使用模板模板参数?

[英]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::stackstd::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_typestd::vector::allocator_type ,从而无需在实际使用时明确提供这些类型类型(即stackContainer )。

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 ,仅用于TContainer<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.

相关问题 为什么 std::array 需要大小作为模板参数而不是构造函数参数? - Why does std::array require the size as a template parameter and not as a constructor parameter? 为什么模板参数解包有时不适用于 std::function? - Why does template parameter unpacking sometimes not work for std::function? 为什么 std::apply 使用函数模板失败,而不使用带有显式模板参数列表的 lambda 表达式? - Why does std::apply fail with function template, but not with a lambda expression with explicit template parameter list? 在std :: exchange中,为什么第二个模板参数是默认的? - In std::exchange, why is the second template parameter defaulted? 如何在std :: bind中使用模板函数参数? - How to use template function parameter in std::bind? 可以使用functor作为std :: function的模板参数吗? - Is possible to use functor as template parameter to std::function? 使用 const lvalue std::array 作为模板参数 - Use const lvalue std::array as template parameter 为什么std :: copy_n采用模板参数而不是std :: size_t? - Why does std::copy_n take a template parameter instead of std::size_t? std :: function作为模板模板参数 - std::function as template template parameter 当模板参数要求 std::less 时,编译器如何在 std::set 中使用 T::operator&lt;<T> ? - How does a compiler use T::operator< in std::set when the template parameter asks for std::less<T>?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM