17

型が特定のテンプレートのインスタンス化であることを確認することは可能ですか?

テンプレート パラメーターの 1 つが特定のテンプレートのインスタンス化か、その他の型のいずれかでなければならないクラス テンプレートがあります。たとえば、次のタイプリストの簡単な定義を考えてみましょう。

struct null_type;

template <typename Head, typename Tail>
struct typelist
{
    // Tail must be a typelist or null_type

    typedef Head head;
    typedef Tail tail;
};

Tailここで、テンプレート パラメーターに提供される型が常に または のインスタンス化であるtypelistことを確認したいと思いますnull_type。次のように、部分的な特殊化を使用して、そのような場合にのみテンプレートを定義できます。

template <typename Head, typename Tail>
struct typelist; // default, not defined

template <typename Head, typename H, typename T>
struct typelist< Head, typelist<H,T> > // Tail = typelist, ok
{
    typedef Head head;
    typedef typelist<H,T> tail;
};

template <typename Head>
struct typelist< Head, null_type > // Tail = null_type, ok
{
    typedef Head head;
    typedef null_type tail;
};

ただし、コードを複製することになります。これは避けたいことです。理想的には、型がテンプレートのインスタンス化であるかどうかをテストし、それenable_ifを静的アサーションで、または静的アサーションで使用するための特性が必要です。

#include <boost/mpl/or.hpp>
#include <type_traits>

struct null_type;

template <typename Head, typename Tail>
struct typelist
{
    static_assert(
        boost::mpl::or_<
            is_instantiation_of< typelist, Tail >,
            std::is_same< Tail, null_type >
        >::value,
        "Tail must be a typelist or null_type" );

    typedef Head head;
    typedef Tail tail;
};

そのような特性 ( is_instantiation_of) は、標準ライブラリまたは Boost で既に利用可能ですか? 1つ書くことは可能ですか?

4

1 に答える 1

24

C ++ 11の可変個引数テンプレートと単純な部分特殊化を使用して、次の解決策を思いつきました。

#include <type_traits>

template < template <typename...> class Template, typename T >
struct is_instantiation_of : std::false_type {};

template < template <typename...> class Template, typename... Args >
struct is_instantiation_of< Template, Template<Args...> > : std::true_type {};

プリプロセッサを使用してさまざまな数のテンプレートパラメータのバージョンを生成することにより、C ++ 03に適合させることができますが、もっと簡単な方法があるかもしれません。

于 2012-06-28T19:16:45.910 に答える