是否可以检查某个类型是否是特定模板的实例化?
我有一个类模板,其中一个模板参数必须是特定模板的实例化,或其他类型。例如,考虑一个类型列表的简单定义:
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;
};
标准库或Boost中是否已提供此类特征(is_instantiation_of
)?有可能写一个吗?
答案 0 :(得分:20)
我提出了以下解决方案,使用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,但可能有一种更简单的方法。