Вы должны сделать два шага. Нахождение целочисленного типа, достаточно большого для хранения значений. Вы можете использовать unsigned long
, но значения могут быть отрицательными. Тогда вы можете использовать long
, но значения могут выходить за пределы unsigned long
. Так что на самом деле нет подходящего типа.
Однако есть хитрость с использованием разрешения перегрузки. Вот оно
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);
Вы можете изменить его соответствующим образом, чтобы охватить также long long
или unsigned long long
, если ваша реализация поддерживает это. Теперь при передаче типа enum предпочтение будет отдаваться одному из них по сравнению со всеми остальными - это тип, который может хранить все его значения. Вам просто нужно передать sizeof
возвращаемого типа в некоторый шаблон.
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; };
Теперь вы можете получить правильный тип. Все, что вам нужно сейчас, это посмотреть, является ли какой-то тип перечислением. Как это сделать, описано в книге «Шаблоны C ++ - Полное руководство», и, к сожалению, здесь много кода. Так что я бы использовал буст is_enum
. Соедини это, это могло бы быть похоже на
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;
}
Надеюсь, это поможет.