You have to do two steps. Finding an integral type large enough to store the values. You could use unsigned long
, but the values could be negative. Then you could use long
but the values could extend into the range of unsigned long
. So there is not really a fit-it-all type.
There is a trick though, by using overload resolution. Here is it
template<typename T>
struct id { typedef T type; };
id<char[1]>::type &find_etype(int);
id<char[2]>::type &find_etype(unsigned int);
id<char[3]>::type &find_etype(long);
id<char[4]>::type &find_etype(unsigned long);
You can change it appropriately to cover also long long
or unsigned long long
if your implementation has support for that. Now, passing an enum type will prefer one of these over all the other ones - that's a type that can store all values of it. You just need to pass sizeof
of the return type to some template.
template<int> struct get_etype;
template<> struct get_etype<1> { typedef int type; };
template<> struct get_etype<2> { typedef unsigned int type; };
template<> struct get_etype<3> { typedef long type; };
template<> struct get_etype<4> { typedef unsigned long type; };
Now, you can get a right type. All you need now is to see whether some type is an enumeration. How to do this is described in the book "C++ Templates - The complete Guide", and unfortunately is a whole lot of code. So i would use boost's is_enum
. Putting it together, it could look like
template <typename T>
typename boost::disable_if< boost::is_enum<T>, bool>::type
ConvertString(const std::string& theString, T& theResult)
{
std::istringstream iss(theString);
return !(iss >> theResult).fail();
}
template <typename T>
typename boost::enable_if< boost::is_enum<T>, bool>::type
ConvertString(const std::string& theString, T& theResult)
{
typedef typename get_etype<sizeof find_etype(theResult)>::type
safe_type;
std::istringstream iss(theString);
safe_type temp;
const bool isValid = !(iss >> temp).fail();
theResult = static_cast<T>(temp);
return isValid;
}
Hope this helps.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…