1

テンプレートクラスがあるとします:

template <typename T> class StringDeque:
public std::deque<T>
{
public:

    ...

private:
    typedef std::deque<T> BaseClass; 
};

ArrayString具体的なクラスwhereを作成したいとしますT=std::string。それを達成するための適切な方法は何ですか:

定義

#define ArrayString StringDeque<string>

typedef

typedef StringDeque < string > ArrayString;

継承

class ArrayString :
    public StringDeque < string > {};

すべての提案が有効かどうかはわかりません。とにかく、どの練習が最も適しているかを理解しようとしています。

4

3 に答える 3

3

特定の型 (たまたまテンプレートのインスタンス化) に名前を付けたいとします。型に名前 (エイリアス) を与える C++ の方法は、typedef を使用することです。

typedef StringDeque<string> ArrayString;

または、C++11 以降では、エイリアス宣言を使用します。

using ArrayString = StringDeque<string>;

補足: このようなことを考えるときは、通常、正しいテンプレート用語の観点から考えることが役立ちます。「テンプレート クラス」(特別なプロパティを持つクラス) はありません。「クラス テンプレート」(クラスを作成するためのテンプレート) があります。テンプレートは型ではありません。そのインスタンス化は.

于 2014-09-11T07:06:55.263 に答える
2

適切な方法:

typedef std::deque<std::string> StringDeque;
using StringDeque = std::deque<string>;

とはいえ、ここにあなたの質問に関するいくつかのメモがあります:

あなたが書いた:

template <typename T> class StringDeque: public std::deque<T> // ...

stdコンテナ クラスは基本クラスとして意味されていません。これは、それらを継承してはならないことを意味します (そして、それらからの継承は UB です)。

別のクラスでコンテナー機能を使用する場合std、答えは常にカプセル化する必要があります。つまり、クラスで std::queue の機能を構築する正しい方法は次のとおりです。

template<typename T> class StringDequeue {
    std::deque<T> storage;
public:
    // add interface here that uses storage
};

あなたはこれも提案しました:

#define ArrayString StringDeque<string>

define を使用して型を宣言しないでください。動作しますが、独自の落とし穴があり、C++ では悪い習慣と見なされています。

于 2014-09-11T07:52:47.243 に答える
1

or を使用して型エイリアスを作成しますtypedef(C++11以上) using:

typedef StringDeque<std::string> ArrayString;
using ArrayString = StringDeque<std::string>;

プリプロセッサは大ハンマーです。便利な場合もありますが、言語レベルの構造についての知識がないため、驚くべき方法でコードを壊す傾向があります。この場合、唯一の問題は、名前がスコープに制限されないことだと思います。しかし、それはそれを避けるのに十分な理由です。

継承によって新しい型が作成されます。通常、基本型がある場所で使用できますが、完全に交換可能ではなく、基本型からコンストラクターを継承しません。したがって、それは単純な型エイリアスに必要なものでもありません。

于 2014-09-11T07:11:29.803 に答える