use*_*508 3 c++ operator-overloading
我有枚举类型,为此我重载了operator>>.
std::istream& operator >>(std::istream &is,MyEnum& enumVar)
{
int intVal;
is>>intVal;
enumVar = intVal;
return is;
}
Run Code Online (Sandbox Code Playgroud)
如何避免为所有未来的枚举类型编写此代码,即如何编写函数使其适用于所有枚举类型?
使操作符成为模板并仅在模板参数是枚举时启用它(使用enable_if):
#include <type_traits>
template<typename T>
typename std::enable_if<std::is_enum<T>::value, std::istream&>::type
operator >>(std::istream &is, T& enumVar)
{
std::cout << "enum\n"; // just to see it is this one that gets used
int intVal;
is >> intVal;
enumVar = static_cast<T>(intVal); // note the explicit cast to make it legal
return is;
}
Run Code Online (Sandbox Code Playgroud)
如果你没有可用的 C++11,你可以使用 boost 的type_traits库。
看到你的评论,你不知道具体是如何enable_if工作的,这里有一个详细解释的链接。
简而言之,enable_if模板是成对出现的——type当条件(第一个模板参数)为真时,一个带有第二个模板参数的成员 typedef,当条件为假时,一个没有那个 typedef。具有 false 条件的模板实例化无效,因为成员 typedef 不存在。这样的实例化然后(而不是硬编译器错误)从重载集中丢弃,以便以后的重载解析。另请阅读有关SFINAE 的信息。
编辑:boost 的enable_if工作原理与标准的略有不同。使用:
boost::enable_if < boost::is_enum<T>, std::istream& >::type
// ^^^^^^^^^^^^^^^^^
// expects a type
Run Code Online (Sandbox Code Playgroud)
或者
boost::enable_if_c < boost::is_enum<T>::value, std::istream& >::type
// ^^^^^^^^^^^^^^^^^^^^^^^^
// expects a value
Run Code Online (Sandbox Code Playgroud)