41

テンプレート引数として異なるコンテナーを使用してテンプレート クラス (アダプター) を宣言するにはどうすればよいですか? たとえば、クラスを宣言する必要があります。

template<typename T, typename Container>
class MyMultibyteString
{
    Container buffer;
    ...
};

そして、私はそれをベクトルに基づいて欲しいです。ハード定義するにはどうすればよいですか?(誰かがそのような宣言を書くのを防ぐためMyMultibyteString<int, vector<char>>)。

さらに、そのような構造を実装する方法:

MyMultibyteString<int, std::vector> mbs;

テンプレート引数をコンテナに渡さずに。

4

3 に答える 3

80

テンプレート テンプレート パラメータを使用する必要があります。

template<typename T, template <typename, typename> class Container>
//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
    Container<T, std::allocator<T>> buffer;
    // ...
};

これにより、次のように記述できます。

MyMultibyteString<int, std::vector> mbs;

これはライブのコンパイルです。上記を別の方法で書くと、次のようになります。

template<typename T,
    template <typename, typename = std::allocator<T>> class Container>
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
    Container<T> buffer; // <== No more need to specify the second argument here
    // ...
};

そして、これが対応するlive exampleです。

注意しなければならない唯一のことは、テンプレート テンプレート パラメーター宣言の引数の数と型が、テンプレート引数として渡したい対応するクラス テンプレートの定義の引数の数と型と正確に一致する必要があることです。これらのパラメーターの一部にはデフォルト値がある可能性があります。

たとえば、クラス テンプレートstd::vectorは 2 つのテンプレート パラメーター(要素の型とアロケーターの型) を受け入れますが、2 番目のパラメーターには既定値がありますstd::allocator<T>。このため、次のように書くことができませんでした。

template<typename T, template <typename> class Container>
//                             ^^^^^^^^
//                             Notice: just one template parameter declared!
class MyMultibyteString
{
    Container<T> buffer;
    // ...
};

// ...

MyMultibyteString<int, std::vector> mbs; // ERROR!
//                     ^^^^^^^^^^^
//                     The std::vector class template accepts *two*
//                     template parameters (even though the second
//                     one has a default argument)

std::setこれは、 と の両方をテンプレート テンプレート パラメータとして受け入れる単一のクラス テンプレートを作成できないことを意味します。これは、とstd::vector異なりstd::vectorクラス テンプレートは3 つのテンプレート パラメータを受け入れるためです。std::set

于 2013-05-16T20:05:27.823 に答える