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?
Extra level of indirection by using two new type traits:
and then do the
enable_if
on these type traitsNote that you still need to make sure that no user-defined class is added to both groups, or you will get an ambiguity. You can either use @Angew's solution to derive from a numbered group using
std::integral_constant<int, N>
for group numberN
. Or, if these groups are not logically exclusive, you could add an extra condition inside theenable_if
that guards against this.You can also do this with your own traits and without
enable_if
:This has the advantage of automatically ensuring that each type is in at most one group.