Reputation: 4106
I have a class with several strongly typed enums and I want them to be implicitly comparable to int. For that purpose I have written super-simple template function:
template<class T> bool operator==(const T &e, const int &i)
{
return (static_cast<int>(e) == i);
}
and the opposite one
template<class T> bool operator==(const int &i, const T &e)
{
return (e == i);
}
However this might be dangerous because it pretty much writes a blank check for any comparison between class T and an integer. I would therefore want only few explicitly specified instantiations such as
template bool operator==(const MyEnum &e, const int &i);
template bool operator==(const int &i, const MyEnum &e);
and no other. Is there a way to disable all implicit instantiations or achieve this? I can always write both operators for each enum separately of course but templates really seem like a better solution.
Upvotes: 1
Views: 719
Reputation: 96875
Use SFINAE to reject overloads which don't deduce a MyEnum
:
template<class T, std::enable_if_t<std::is_same<T, MyEnum>::value>* = nullptr>
bool operator==(const T &e, const int &i);
template<class T, std::enable_if_t<std::is_same<T, MyEnum>::value>* = nullptr>
bool operator==(const int &i, const T &e);
Due to the comments I have updated my answer. If you want to only accept select few template types then I suggest using this bool_or
trick:
#include <type_traits>
#include <utility>
template<bool... Bs>
using bool_sequence = std::integer_sequence<bool, Bs...>;
template<bool... Bs>
using bool_and = std::is_same<bool_sequence<Bs...>,
bool_sequence<(Bs || true)...>>;
template<bool... Bs>
using bool_or = std::integral_constant<bool, !bool_and<!Bs...>::value>;
template<class T, class... Ts>
using any_same = bool_or<std::is_same<T, Ts>::value...>;
template<class T, std::enable_if_t<any_same<T, MyEnum, X, Y, Z>::value>* = nullptr>
bool operator==(const T &e, const int &i);
template<class T, std::enable_if_t<any_same<T, MyEnum, X, Y, Z>::value>* = nullptr>
bool operator==(const int &i, const T &e);
You can add any number of types to compare with.
Upvotes: 6