【问题标题】:How can I check if a type is an instantiation of a given class template? [duplicate]如何检查类型是否是给定类模板的实例化? [复制]
【发布时间】:2012-06-30 08:53:45
【问题描述】:

是否可以检查一个类型是否是特定模板的实例化?

我有一个类模板,其中一个模板参数必须是特定模板的实例化或其他类型。例如,考虑一个类型列表的这个简单定义:

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 模板参数提供的类型始终是typelistnull_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;
};

但是,我最终会重复代码,这是我想避免的。理想情况下,我需要一个 trait 来测试一个类型是否是模板的实例化,将它与 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;
};

标准库或 Boost 中是否已经提供了这样的特征 (is_instantiation_of)?可以写一个吗?

【问题讨论】:

    标签: c++ templates template-meta-programming


    【解决方案1】:

    我想出了以下解决方案,使用 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,但可能有更简单的方法。

    【讨论】:

    • Tch,我正要点击“发布您的答案”。 :P
    • 顺便说一句,我打电话给 my version is_specialization_of 因为这是正确的术语。 “实例化”是生成“特化”的过程
    • @Xeo:那是不一致的! :P
    • 当心,如果 Template 参数是具有非类型参数的模板,则解决方案会失败,例如template&lt;class T, int I&gt; struct foo{...} (gcc 4.7)
    • 不适用于std::array 和所有此类模板 - 请参阅之前的评论
    猜你喜欢
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    相关资源
    最近更新 更多