Reputation: 3131
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
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