如何检查类型是否是给定类模板的实例化? [英] How can I check if a type is an instantiation of a given class template?

查看:153
本文介绍了如何检查类型是否是给定类模板的实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to check that a type is an instantiation of a particular template?

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

I have a class template where one of the template parameter must be either an instantiation of a particular template, or some other type. For instance, consider this simple definition of a typelist:

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 的实例化。我可以使用部分专门化来定义模板只为那些情况,如下:

Now, I would like to make sure that the type provided for the Tail template parameter is always either an instantiation of typelist or null_type. I could use partial specialization to define the template only for those cases, like this:

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 或静态断言:

However, I end up duplicating code, which is something I would like to avoid. Ideally, I'd need a trait to test whether a type is an instantiation of a template, to use it with enable_if or in static assertions:

#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?可以写一个?

Is such a trait (is_instantiation_of) already available in the standard library or in Boost? Is is possible to write one?

推荐答案

我想出了以下解决方案,使用C ++ 11可变参数模板和简单的partial专业化:

I came up with the following solution, using C++11 variadic templates and simple partial specialization:

#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模板参数,但也许有一个更简单的方法。

It could be adapted to C++03 by using the preprocessor to generate versions for a varying number of template parameters, but there is maybe a simpler way.

这篇关于如何检查类型是否是给定类模板的实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆