4

このプログラムは 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>>、単なるデータ型ではなく 2 つのデータ型について言及しているのかということstack<vector<int>>です。

4

5 に答える 5

3

チェックアウト: http://www.sgi.com/tech/stl/stack.html

テンプレートに 2 つのデータ型パラメーターを持つスタックを作成するstack<T, Sequence> stack;

これは、最初の型パラメーターがスタックが保持する要素の型であり、2 番目の型パラメーターがスタックの実装に使用されるコンテナーの型であるためです。

さまざまなコンテナー タイプを使用すると、さまざまなメモリ割り当て、速度などの利点と欠点が得られます。これは、使用する実装のタイプに関して、消費者としての柔軟性を高めるだけです。

そのリンクから:

Stack はコンテナー アダプターです。つまり、基になるコンテナー タイプの上に実装されます。デフォルトでは、基になる型は deque ですが、別の型を明示的に選択することもできます。

于 2012-10-04T14:43:03.313 に答える
2

重要な点は、これはコンテナーstackではなく、コンテナー アダプターです。

C++ では、コンテナー アダプターは、特定のコンテナーの追加のインターフェイスです。アダプタが使用する標準のコンテナは、一般的にはうまく機能しますが、場合によっては別の基本データ構造を使用したい場合があります。

コンテナ/アダプタとは?も参照してください。C++ .

それらがコンテナーではない理由については、Container Adapters do not support iteratorsを確認してくださいstack


おまけの知識: テンプレート プログラマーは、「なぜ 2 番目のパラメーターがテンプレート テンプレート パラメーターではないのか、

template <typename T, template <typename, typename> class Seq >
struct stack {};

#include <vector>

int main () {
    stack<int, std::vector> s;
}

?」

簡単な答え: これにより、アダプター クラスの機能が大幅に低下します。

  • vectorアダプター クラスは、コンテナーによって使用されるアロケーター ( isの完全な署名std::vector<T, Alloc=...>) を決定する必要があるため、アダプター ユーザーはそれを微調整できませんでした。
  • すべての有効なコンテナーが同じ数と型のテンプレート引数を持っているわけではありません
于 2012-10-05T08:58:19.730 に答える
1

stack<vector<T> >基になるクラスとして vector を使用して T のスタックを意味することができない理由は、T のベクトルのスタックである別の意味を持っているためです。ベクターはスタックの有効な値型です。ベクターをスタックにプッシュしてからポップバックできます...したがって、標準がこの特定のテンプレートパラメーターを (部分的に) 特殊化する理由はありません。

于 2012-10-05T09:16:51.107 に答える
1

これはまさに、標準ライブラリ コンテナー テンプレートが設計される方法です。最初のテンプレート引数は、含まれるデータの型です (連想コンテナーの場合は最初の2 つ)。

たとえば、あなたが提案するように、独自のテンプレートを別の方法で設計することを妨げるものは何もありません。

template <typename Backend>
class my_stack
{
public:
    typedef Backend                         container_type;
    typedef typename container_type::value_type value_type;

private:
    container_type container; 

    // ...
};

ただし、この設計には 2 つの欠点があります。

  1. 最小限でシンプルではありません。s のスタックだけが必要な場合はint、自分でコンテナーを考えなければならず、単に とは言えませんmy_stack<int>

  2. コンテナーに制約を課します。つまり、メンバー型を公開しvalue_typeます。とは言えませんmy_stack<my_insane_container<int>>

さて、次のような方法で 2 番目の不満を克服できます。

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;

    // ...
};

しかし、これでさらにおかしくなりました: コンテナーはテンプレート (つまり bye bye class my_specialized_int_container) である必要があり、その値の型を最初の要素として取得する必要があります (つまり、bye bye stack of stacks)。

要するに、標準ライブラリの設計は非常に賢明です。

于 2012-10-04T16:32:52.433 に答える
0

スタックは STL コンテナーではなく、プログラミング パターンの 1 つであるアダプターです。つまり、スタックを使用してコンテナー (vectorまたはdeque) をラップし、そのパブリック メソッドを「置換」します (新しいパブリック メソッドを作成し、既存のものを非表示にします)。ここでアダプターの詳細を読むことができますhttp://en.wikipedia.org/wiki/Adapter_pattern

于 2012-10-04T14:46:19.193 に答える