元功能检测通过CRTP继承的模板类

时间:2017-05-11 10:23:19

标签: c++ c++11 templates

我有一个如下界面:

template<typename Concrete, typename T>
class Interface{
    ...
}

及其具体实现:

template<typename T>
class Concrete : public Interface<Concrete<T>, T>
{
    ...
    using type = typename T;
}

我想要一个可以检查某个类型是否来自Interface的元函数。

作为一个例子,让我们说界面只有一个模板参数(因此它不会生成子模板类):

template<typename Concrete>
class A
{
    ...
}

class B : public A<B>
{
    ...
}

在这种情况下,我可以使用:

template<typename T>
struct is_A
{
    static bool const value = std::is_base<A<T>, T>::value;
}

我的问题是,对于存在附加模板参数的情况,产生类似元函数的最佳方法是什么。它应该看起来像:

template<typename T>    
struct is_Interface{}

要清楚,我可以制作

 template<template <class> class T>    
 struct is_Interface
 {
  using dummy_type = void;
  static bool const value = std::is_base<Interface<T<dummy_type>, dummy_type>, T<dummy_type>>::value;
 }

但我想要传递具体类型而不是模板类的东西。

1 个答案:

答案 0 :(得分:4)

您可以使用重载解析:

template <template <class> class Concrete, class T>
std::true_type is_Interface_impl(Interface<Concrete<T>, T> *);

std::false_type is_Interface_impl(...);

template<typename T>
struct is_Interface : decltype(is_Interface_impl(std::declval<T*>())) { };

模板参数推导中允许派生到基指针转换,这是is_Interface_impl的第一次重载如何检测和匹配关系。如果转换不可能发生,则应用SFINAE并且重载决策会回退到vararg函数。

See it live on Coliru!