Use std::enable_if:
template <typename T>
struct is_overvoid_or_meta
{
static const bool value = false;
};
template <> struct is_overvoid_or_meta<OverVoid>
{
static const bool value = true;
};
template <> struct is_overvoid_or_meta<Meta>
{
static const bool value = true;
};
//Add specialization for all valid types - this allows you to more precisely tell, what types can be used as a template argument for Move
And then:
template<typename _Ty>
class Move
{
typedef std::enable_if<is_overvoid_or_meta<_Ty>::value, _Ty>::type Type;
};
You will get compile-time error for every type, that is not OverVoid
or Meta
(or, more general, for every T
, for which is_overvoid_or_meta<T>::value
is false
- if you will add more of them in the future, you may want to chnge is_overvoid_or_meta
to more general, like is_acceptable_by_move
or something):
int main()
{
Move<OverVoid> m1;
Move<Meta> m2;
Move<int> m3;
return 0;
}
Output:
error: no type named 'type' in 'struct std::enable_if'
typedef typename std::enable_if::value, _Ty>::type Type;
Live sample.
This is very nice solution, because it cannot be tricked - additional template parameter for Move
can always be specified manually (unless OverVoid
and Meta
are not exposed to client).