3

我有枚举类型,为此我重载了operator>>.

std::istream& operator >>(std::istream &is,MyEnum& enumVar)
{
  int intVal;
  is>>intVal;
  enumVar = intVal;
  return is;
}

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

4

1 回答 1

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;
}

如果你没有可用的 C++11,你可以使用 boost 的type_traits库。

看到您不知道确切如何enable_if工作的评论,这里是一个带有详细解释的链接。

简而言之,enable_if模板是成对出现的——一个在条件(第一个模板参数)为真时具有第二个模板参数的成员 typedef type,而在条件为假时没有该 typedef。具有 false 条件的模板实例化无效,因为成员 typedef 不存在。然后,这种实例化(而不是硬编译器错误)从重载集中丢弃,以供以后的重载解决。另请阅读有关SFINAE的信息。

编辑:boost 的enable_if工作方式与标准的略有不同。使用任一:

boost::enable_if < boost::is_enum<T>, std::istream& >::type
                // ^^^^^^^^^^^^^^^^^
                // expects a type

或者

boost::enable_if_c < boost::is_enum<T>::value, std::istream& >::type
                  // ^^^^^^^^^^^^^^^^^^^^^^^^
                  // expects a value
于 2013-04-02T10:02:07.463 回答