这是练习std::enable_if ,std::is_same 和 std::decay 的例子。
用来做字符串转化的泛型有些牵强,实际上这块用函数模版特化可能会更合适。
至于什么时候用std::enable_if 看《C++程序设计语言》的元编程讲std::enable_if有个更合适的例子。
#include <string>
#include <type_traits>
namespace detail {
template<class T, class Enable = void>
struct ConvertToNumeric
{
T operator()(const std::string& str) const
{
return std::stoi(str);
}
};
//special cases
template< bool B, class T>
using T_enable_if_t = typename std::enable_if<B,T>::type;
template<class U, class T>
using T_same_enable_t = T_enable_if_t<std::is_same<T,U>::value, T>;
template<class T>
struct ConvertToNumeric<T, T_same_enable_t<long, T>>
{
long operator()(const std::string& str) const
{
return std::stol(str);
}
};
template<class T>
struct ConvertToNumeric<T, T_same_enable_t<unsigned long, T>>
{
unsigned long operator()(const std::string& str) const
{
return std::stoul(str);
}
};
template<typename T>
struct ConvertToNumeric<T, T_same_enable_t<long long, T>>
{
long long operator()(const std::string& str) const
{
return std::stoll(str);
}
};
template<typename T>
struct ConvertToNumeric<T, T_same_enable_t<unsigned long long, T>>
{
unsigned long long operator()(const std::string& str) const
{
return std::stoull(str);
}
};
template<typename T>
struct ConvertToNumeric<T, T_same_enable_t<float, T>>
{
float operator()(const std::string& str) const
{
return std::stof(str);
}
};
template<typename T>
struct ConvertToNumeric<T, T_same_enable_t<double, T>>
{
double operator()(const std::string& str) const
{
return std::stod(str);
}
};
template<typename T>
struct ConvertToNumeric<T, T_same_enable_t<long double, T>>
{
long double operator()(const std::string& str) const
{
return std::stold(str);
}
};
}
//this complex way, also use function template specialization
/*****************************************/
/*
template<typename T>
inline T str_to_numeric(const std::string& str)
{
return std::stoi(str);
}
template<>
inline long str_to_numeric<long>(const std::string& str)
{
return std::stol(str);
}
...
*/
template<typename T>
inline T str_to_numeric(const std::string& str)
{
using T_decay_t = typename std::decay<T>::type;
return detail::ConvertToNumeric<T_decay_t, T_decay_t>()(str);
}
原文:https://www.cnblogs.com/water-bear/p/11940461.html