Converting a string to real number

This is an example of practice std :: enable_if, std :: is_same and std :: decay of. 
Generic string used for conversion of far-fetched, in fact, with this specialized function template may be more appropriate.
As for when to use std :: enable_if see "C ++ Programming Language" meta-programming speak std :: enable_if there is a more appropriate example.
 
 #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);
}

Guess you like

Origin www.cnblogs.com/water-bear/p/11940461.html