Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;std::字符串到数字模板_C++_C++11_Templates_Std_Stdstring - Fatal编程技术网

C++ C++;std::字符串到数字模板

C++ C++;std::字符串到数字模板,c++,c++11,templates,std,stdstring,C++,C++11,Templates,Std,Stdstring,我目前正在尝试实现我自己的标准输入阅读器供个人使用。我创建了一个从标准输入读取整数的方法,并对其有效性进行了一些检查。其思想是,我从标准输入中读取一个字符串,执行几次检查,转换为int,执行最后一次检查,返回已读取的值。如果在检查期间发生任何错误,我将只填写一个errorHint,在std::cerr上打印,并返回std::numeric\u limits::min() 我认为这个想法很简单,很容易实现,现在我想概括这个概念并制作方法模板,所以基本上我可以在编译时选择,无论何时我需要从标准输入中

我目前正在尝试实现我自己的标准输入阅读器供个人使用。我创建了一个从标准输入读取整数的方法,并对其有效性进行了一些检查。其思想是,我从标准输入中读取一个字符串,执行几次检查,转换为int,执行最后一次检查,返回已读取的值。如果在检查期间发生任何错误,我将只填写一个
errorHint
,在
std::cerr
上打印,并返回
std::numeric\u limits::min()

我认为这个想法很简单,很容易实现,现在我想概括这个概念并制作方法模板,所以基本上我可以在编译时选择,无论何时我需要从标准输入中读取我想要的整数类型(它可以是
int
long
long
无符号long
等等,但可以是一个整数)。为此,我创建了以下静态模板方法:

template<
    class T,
    class = typename std::enable_if<std::is_integral<T>::value, T>::type
> 
static T getIntegerTest(std::string& strErrorHint,
                        T nMinimumValue = std::numeric_limits<T>::min(),
                        T nMaximumValue = std::numeric_limits<T>::max());
模板<
T类,
class=typename std::enable\u if::type
> 
静态T getIntegerTest(std::string和strerrorrhint,
T nMinimumValue=std::numeric_limits::min(),
T nMaximumValue=std::numeric_limits::max());
并在同一.hpp文件中实现以下几行:

template<
    class T,
    class>
T InputReader::getIntegerTest(std::string& strErrorHint,
                              T nMinimumValue,
                              T nMaximumValue)
{
    std::string strInputString;
    std::cin >> strInputString;

    // Do several checks

    T nReturnValue = std::stoi(strInputString); /// <--- HERE!!!

    // Do other checks on the returnValue

    return nReturnValue;
}
模板<
T类,
类别>
输入读取器::getIntegerTest(标准::字符串和strerrorRhint,
T最小值,
T n最大值)
{
std::strInputString字符串;
std::cin>>strInputString;
//做几次检查

T nReturnValue=std::stoi(strInputString);//专门化函数对象是基于类型特征修改行为的一种非常通用的方法

方法是:

  • 为操作定义常规模板

  • 专门制作角落案例的模板

  • 通过helper函数调用

  • 例如:

    #include <iostream>
    #include <type_traits>
    #include <string>
    
    
    namespace detail {
    /// general case
        template<class Integer, typename Enable = void>
        struct convert_to_integer {
            Integer operator()(std::string const &str) const {
                return std::stoi(str);
            }
        };
    
    // special cases
        template<class Integer>
        struct convert_to_integer<Integer, std::enable_if_t<std::is_same<long, Integer>::value> > {
            long operator()(std::string const &str) const {
                return std::stol(str);
            }
        };
    }
    
    template<class T, class StringLike>
    T to_integral(StringLike&& str)
    {
        using type = std::decay_t<T>;
        return detail::convert_to_integer<type>()(str);
    };
    
    int main() {
    
        std::string t1 = "6";
        const char t2[] = "7";
    
        std::cout << to_integral<int>(t1) << std::endl;
        std::cout << to_integral<int>(t2) << std::endl;
    
        // will use the specilaisation
        std::cout << to_integral<long>(t1) << std::endl;
        std::cout << to_integral<long>(t2) << std::endl;
    
        // will use the default case
        std::cout << to_integral<short>(t1) << std::endl;
        std::cout << to_integral<short>(t2) << std::endl;
    }
    
    #包括
    #包括
    #包括
    名称空间详细信息{
    ///一般情况
    样板
    结构转换为整数{
    整型运算符()(std::string const&str)const{
    返回std::stoi(str);
    }
    };
    //特例
    样板
    结构转换为整数{
    长运算符()(std::string const&str)const{
    返回std::stol(str);
    }
    };
    }
    样板
    T到_积分(类似字符串和str)
    {
    使用类型=标准::衰减\u t;
    返回详细信息::将_转换为_整数()(str);
    };
    int main(){
    std::string t1=“6”;
    常量字符t2[]=“7”;
    
    std::cout专门化函数对象是基于类型特征修改行为的一种非常通用的方法

    方法是:

  • 为操作定义常规模板

  • 专门制作角落案例的模板

  • 通过helper函数调用

  • 例如:

    #include <iostream>
    #include <type_traits>
    #include <string>
    
    
    namespace detail {
    /// general case
        template<class Integer, typename Enable = void>
        struct convert_to_integer {
            Integer operator()(std::string const &str) const {
                return std::stoi(str);
            }
        };
    
    // special cases
        template<class Integer>
        struct convert_to_integer<Integer, std::enable_if_t<std::is_same<long, Integer>::value> > {
            long operator()(std::string const &str) const {
                return std::stol(str);
            }
        };
    }
    
    template<class T, class StringLike>
    T to_integral(StringLike&& str)
    {
        using type = std::decay_t<T>;
        return detail::convert_to_integer<type>()(str);
    };
    
    int main() {
    
        std::string t1 = "6";
        const char t2[] = "7";
    
        std::cout << to_integral<int>(t1) << std::endl;
        std::cout << to_integral<int>(t2) << std::endl;
    
        // will use the specilaisation
        std::cout << to_integral<long>(t1) << std::endl;
        std::cout << to_integral<long>(t2) << std::endl;
    
        // will use the default case
        std::cout << to_integral<short>(t1) << std::endl;
        std::cout << to_integral<short>(t2) << std::endl;
    }
    
    #包括
    #包括
    #包括
    名称空间详细信息{
    ///一般情况
    样板
    结构转换为整数{
    整型运算符()(std::string const&str)const{
    返回std::stoi(str);
    }
    };
    //特例
    样板
    结构转换为整数{
    长运算符()(std::string const&str)const{
    返回std::stol(str);
    }
    };
    }
    样板
    T到_积分(类似字符串和str)
    {
    使用类型=标准::衰减\u t;
    返回详细信息::将_转换为_整数()(str);
    };
    int main(){
    std::string t1=“6”;
    常量字符t2[]=“7”;
    
    std::cout
    bool success=std::cin>>T_instance;
    ,然后(另一个)范围检查…为什么不简单地使用
    std::istringstream
    bool success=std::cin>>T_instance;
    ,然后(另一个)范围检查…为什么不直接使用
    std::istringstream
    ?感谢您的回答@Richard Hodges!非常好!我非常感谢!对于异常,为什么您认为抛出异常比使用错误提示更好?特别是我想您会建议创建我自己的错误类型,并在失败时抛出该类型这是正确的吗?@user2271691理想情况下是您自己的错误类型,从std::runtime_error或std::invalid_参数派生。谢谢您的回答@Richard Hodges!非常好!我非常感谢!对于异常,为什么您认为抛出异常比使用错误提示更好?特别是我想您会建议创建我自己的错误类型,并在发生故障时抛出该错误是否正确?@user2271691理想情况下是您自己的错误类型,派生自std::runtime\u error或std::invalid\u参数。