我有一个包含多个强类型枚举的类,我希望它们可以隐式地与 int 进行比较。为此,我编写了 super 简单的模板函数:
template<class T> bool operator==(const T &e, const int &i)
{
return (static_cast<int>(e) == i);
}
和相反的
template<class T> bool operator==(const int &i, const T &e)
{
return (e == i);
}
但是这可能很危险,因为它几乎为类 T 和整数之间的任何比较写了一张空白支票。因此,我只想要一些明确指定的实例化,例如
template bool operator==(const MyEnum &e, const int &i);
template bool operator==(const int &i, const MyEnum &e);
没有别的。有没有办法禁用所有隐式实例化或实现这一点?当然,我总是可以为每个枚举单独编写两个运算符,但模板似乎确实是更好的解决方案。
最佳答案
<罢工>
使用 SFINAE 拒绝不推导出 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);
罢工><罢工>罢工>
由于评论,我更新了我的答案。如果您只想接受选择的几种模板类型,那么我建议使用此 bool_or
技巧:
#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);
您可以添加任意数量的类型进行比较。
关于c++ - 如何防止模板函数的隐式实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32288371/