专门化模板派生类的函数模板

时间:2014-01-15 17:26:11

标签: c++ templates c++11 template-specialization

我基本上有一个std::integral_constant的模拟版本,其中包含一个变量,我想专门为从Base<T>派生的这些类的函数模板,如下所示:

template<class T> struct Base{
  typedef T type;
  T t;
};

template<class T> struct A : Base<T>{
  static constexpr T value = 1;
};
template<class T> struct B : Base<T>{
  static constexpr T value = 2;
};

struct Unrelated{};

// etc.

template<class T> void foo(T t){
  //I would like to specialize foo for A and B and have a version for other types
}


int main(){
  foo(A<float>());//do something special based on value fields of A and B
  foo(B<float>());
  foo(Unrelated()); //do some default behavior
}

以下是主要问题:

  • 我无法将value作为模板包含在内,因为我期待T = doublefloat或其他一些非整数类型(否则我只会扩展std::integral_constant
  • 我无法干净地使用std::is_base,因为我必须std::is_base<Base<T::type>,T>
  • 执行foo(Base<T>&)不允许我看到value,我不想诉诸虚拟value()功能(或反思)。
  • 显然我想避免为每个派生类专门化foo。

我认为答案在于使用is_base,但无论我如何尝试使用它,我都无法将其付诸实践。我错过了一个更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

以下内容应该有效:

template<typename,typename = void>
struct IsBase
  : std::false_type {};

template<typename T>
struct IsBase<T, typename std::enable_if<
                   std::is_base_of<Base<typename T::type>,T>::value
                 >::type>
  : std::true_type {};

template<class T>
typename std::enable_if<IsBase<T>::value>::type foo(T t){
    // use T::value
}

template<class T>
typename std::enable_if<!IsBase<T>::value>::type foo(T t){
    // general case
}

Live example