此程序取自cplusplus.com
#include <iostream>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
int main ()
{
deque<int> mydeque (3,100); // deque with 3 elements
vector<int> myvector (2,200); // vector with 2 elements
stack<int> first; // empty stack
stack<int> second (mydeque); // stack initialized to copy of deque
stack<int,vector<int> > third; // empty stack using vector
stack<int,vector<int> > fourth (myvector);
cout << "size of first: " << (int) first.size() << endl;
cout << "size of second: " << (int) second.size() << endl;
cout << "size of third: " << (int) third.size() << endl;
cout << "size of fourth: " << (int) fourth.size() << endl;
return 0;
}
我无法理解的是,为什么我们提到stack<int, vector<int>>
,即两种数据类型而不只是stack<vector<int>>
?
答案 0 :(得分:3)
退房:http://www.sgi.com/tech/stl/stack.html
为模板创建一个包含两个数据类型参数的堆栈stack<T, Sequence> stack;
完成是因为第一个类型参数是堆栈所包含的元素类型,第二个类型参数是用于实现堆栈的容器类型。
使用不同的容器类型可以为您提供不同的内存分配,速度等方面的优点和缺点。它只是让您在消费者希望使用的实现类型方面具有更大的灵活性。
从该链接:
Stack是一个容器适配器,意味着它是在上面实现的 一些底层容器类型。默认情况下,底层类型是 deque,但可以明确选择不同的类型。
答案 1 :(得分:2)
重点是stack
不是容器,而是容器适配器。
在C ++中,容器适配器是给定容器的附加接口。适配器使用的标准容器在一般情况下运行良好,但有时您可能希望使用不同的基础数据结构。
另见What are Containers/Adapters? C++。
为什么它们不是容器,请查看Container Adapters do not support iterators,其中举例说明了stack
不提供迭代器。
奖金知识:模板程序员可能会问“为什么第二个参数不是模板模板参数,比如
template <typename T, template <typename, typename> class Seq >
struct stack {};
#include <vector>
int main () {
stack<int, std::vector> s;
}
?“
快速回答:这会大大降低适配器类的功能。
vector
的完整签名是std::vector<T, Alloc=...>
),因此适配器用户无法对其进行微调答案 2 :(得分:1)
这就是标准库容器模板的设计方式:第一个模板参数是包含数据的类型(或者第一个两个用于关联容器)。
没有什么可以阻止您以不同方式设计自己的模板,例如像你建议的那样:
template <typename Backend>
class my_stack
{
public:
typedef Backend container_type;
typedef typename container_type::value_type value_type;
private:
container_type container;
// ...
};
然而,这种设计有两个缺点:
它不是简单而简单的。如果我只想要一堆int
s,我必须自己想一个容器,我不能只说my_stack<int>
。
它对容器施加约束,即它公开成员类型value_type
。我不能说my_stack<my_insane_container<int>>
。
现在,您可以通过以下方式克服第二次投诉:
template <typename> class my_crazy_stack;
template <template <typename ...> class Tmpl, typename T, typename ...Args>
class my_cazy_stack<Tmpl<T, Args...>>
{
public:
typedef Tmpl<T, Args...> container_type;
typedef T value_type;
// ...
};
但是现在你让它变得更加疯狂:容器现在需要成为一个模板(即再见class my_specialized_int_container
),它需要 值键入作为第一个元素(即再见堆栈的堆栈)。
因此,简而言之,标准库设计非常合理。
答案 3 :(得分:1)
你不能把stack<vector<T> >
用来表示使用向量作为底层类的T的堆栈的原因仅仅是因为它具有不同的含义,它将是T的向量堆栈。你会期望它意味着那不是吗?向量是堆栈的有效值类型,您可以将向量推送到堆栈然后将其弹回...所以没有理由为什么标准会(部分地)专门化这个特定的模板参数。
答案 4 :(得分:0)
Stack不是STL容器,而是适配器,它是编程模式之一。简而言之,这意味着,该堆栈用于包装容器(vector
或deque
)以“替换”其公共方法(创建新的公共方法并隐藏现有方法)。您可以在此处阅读有关适配器的更多信息http://en.wikipedia.org/wiki/Adapter_pattern