Group class template specializations

c++, c++11, enable-if, templates, traits

Solution

You can also do this with your own traits and without `enable_if`:

// Traits

template <class T>
struct group_number : std::integral_constant<int, 0> {};

template <>
struct group_number<Line> : std::integral_constant<int, 1> {};

template <>
struct group_number<Ray> : std::integral_constant<int, 1> {};

template <>
struct group_number<Linestring> : std::integral_constant<int, 2> {};

template <>
struct group_number<Curve> : std::integral_constant<int, 2> {};


// Foo

template <class T, int Group = group_number<T>::value>
class Foo
{
  //::: whatever
};

template <class T>
class Foo<T, 1>
{
  //::: whatever for group 1
};

template <class T>
class Foo<T, 2>
{
  //::: whatever for group 2
};

This has the advantage of automatically ensuring that each type is in at most one group.

Problem

Is there a technique / best style to group class template specializations for certain types ? An example : Lets say I have a class template `Foo` and I need to have it specialized the same for the typeset ``` A = { Line, Ray } ``` and in another way for the typeset B ``` B = { Linestring, Curve } ``` What I'm doing so far : (the technique is also presented here for functions) ``` #include <iostream> #include <type_traits> using namespace std; // 1st group struct Line {}; struct Ray {}; // 2nd group struct Curve {}; struct Linestring {}; template<typename T, typename Groupper=void> struct Foo { enum { val = 0 }; }; // specialization for the 1st group template<typename T> struct Foo<T, typename enable_if< is_same<T, Line>::value || is_same<T, Ray>::value >::type> { enum { val = 1 }; }; // specialization for the 2nd group template<typename T> struct Foo<T, typename enable_if< is_same<T, Curve>::value || is_same<T, Linestring>::value >::type> { enum { val = 2 }; }; int main() { cout << Foo<Line>::val << endl; cout << Foo<Curve>::val << endl; return 0; } ``` An extra helper struct `enable_for` would shorten the code (and allow to write the accepted types directly). Any other suggestions, corrections? Shouldn't this involve less effort?

Original source

Related problems