Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specializing function template for templated derived class

I essentially have a mock version of std::integral_constant that includes a variable and I want to specialize a function template for these classes derived from Base<T>, like this:

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
}

Here are the main issues:

  • I cannot include value as a template as I am expecting T = double, float, or some other non-integral types (otherwise I'd just extend std::integral_constant)
  • I can't cleanly use std::is_base as I would have to do std::is_base<Base<T::type>,T>
  • Doing foo(Base<T>&) wouldn't allow me to see value and I don't want to have to resort to a virtual value() function (or reflection).
  • And obviously I would like to avoid specializing foo for every derived class.

I think the answer lies in using is_base but I haven't been able to get it to work no matter how I tried to use it. Is there a much simpler way I am missing?

like image 387
user783920 Avatar asked Nov 11 '22 14:11

user783920


1 Answers

The following should work:

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

like image 146
Daniel Frey Avatar answered Nov 15 '22 06:11

Daniel Frey