2016-02-25 37 views
1

我试图通过boost::lexical_cast子串(由一对迭代的表示)转换为整数:意外结果与升压:: iterator_range的

#include <iostream> 
#include <boost/lexical_cast.hpp> 

int main() 
{ 
    // assume [first, last) as substring 
    const std::string s("80"); 
    auto first = s.begin(), last = s.end(); 

    std::cout << boost::lexical_cast<int>(boost::make_iterator_range(first, last)) << std::endl; 
    return 0; 
} 

输出:(wandbox

1 

我得到了预期结果(80)的解决方法:boost::make_iterator_range(&*first, last - first)

问题为什么上面的代码不能按预期方式工作?而且,1从哪里来?

  1. lexical_cast不支持iterator_range<std::string::(const_)iterator>滥用lexical_castlexical_castiterator_range
  2. 错误或iterator_range
  3. 一些其他原因

回答

1

简短的答案是2号从你的列表中,滥用

  • iterator_range - 特别是你使用它没有明确包括适当头为它。

    添加此:

    #include <boost/range/iterator_range.hpp> 
    

    将使其行为像您期望。

    iterator_range和相关功能被分成两个标头,iterator_range_core.hppiterator_range_io.hpp。第一个包含类定义,第二个包含重载,这使得它可以流式传输,因此可用于lexical_cast(可用于实际上将按预期工作)。

    因为你没有包含正确的头文件,通常应该会得到一个编译器错误,但在这种情况下,你不会得到它,因为lexical_cast.hpp包含这两个头文件中的第一个,iterator_range_core.hpp。这使得一切正常,但它不会从第二个标题获得operator<<。如果没有这种过载,当lexical_cast将范围写入流以执行转换时,它发现的最佳过载是采用参数bool的参数(因为iterator_range的默认转换为bool)。这就是为什么你看到1,因为它实际上是true到底层的转换流。

    你可以像这样的东西很容易测试:

    auto someRange = boost::make_iterator_range(first, last); 
    std::cout << std::boolalpha<< someRange; 
    

    没有#include <boost/range/iterator_range.hpp>这将打印true,与include它将打印字符串(80)。

  • +0

    优秀的分析。 – sehe

    +0

    很好的回答,谢谢! – kakkoko