user152508
user152508

Reputation: 3131

Overload operator >> for all enum types

I have enumeration type , for which I overload the operator>>.

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

How to avoid writing this code for all future enum types, i.e how to write the function so it is applicable to all enum types?

Upvotes: 3

Views: 1625

Answers (1)

jrok
jrok

Reputation: 55395

Make the operator a template and enable it only if the template parameter is an enum (using 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;
}

If you don't have C++11 avaliable, you can use boost's type_traits library.

Seeing your comment that you don't know exactly how enable_if works, here is a link with a detailed explanation.

In short, enable_if templates come in pairs - one with a member typedef of second template parameter to type when the condition (first template parameter) is true, and one without that typedef when condition is false. Template instantiations with false condition are invalid, because the member typedef does not exist. Such instantiation is then (instead of being a hard compiler error) discarded from overload set for later overload resolution. Read also about SFINAE.

EDIT: boost's enable_if works slightly differently than the standard one. Use either:

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

or

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

Upvotes: 5

Related Questions