重载运算符 >> 适用于所有枚举类型

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)

如何避免为所有未来的枚举类型编写此代码,即如何编写函数使其适用于所有枚举类型?

jro*_*rok 5

使操作符成为模板并仅在模板参数是枚举时启用它(使用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)