使用lexical_cast到无符号类型时检查负值

时间:2012-11-02 16:09:13

标签: c++ boost

我遇到的情况是我抓住命令行参数并使用boost::lexical_cast<unsigned long>(my_param)。我希望my_param的负值会导致lexical_cast抛出,但是它很乐意转换它们,-1变为18446744073709551615。这似乎很荒谬,因为无符号长整数的最大值是2 ^ 32-1,它看起来更像是无符号长long。

所以我正在寻找一种更聪明的方法将char *输入转换为unsigned long,或者是一种验证我没有在伪装中接受负值的方法作为一个大的无符号long long。

2 个答案:

答案 0 :(得分:6)

有一个错误报告反对你的问题提升,这解释了为什么它的行为:

  

boost :: lexical_cast具有stringstream的行为,它使用std :: locale的num_get函数来转换数字。如果我们看一下编程语言的[22.2.2.1.2] - C ++(或[22.2.2.1.2]工作草案,编程语言C ++标准),我们会看到,num_get使用scanf的规则进行转换。在%u的C99标准中,输入值减号是可选的,因此如果读取负数,则不会出现错误,结果将是二进制补码。

还有一个建议的包装解决方法:

https://svn.boost.org/trac/boost/ticket/5494

答案 1 :(得分:1)

这正是按照标准处理负值的方式。他们使用modulo 2 N 算法。这可以实现一个方便的技巧:使用-1作为某种类型的最大可能无符号值的简写。

如果你不喜欢这种转换,你必须在进行转换之前扫描输入一个减号。