c++ - boost::range::detail::any_iterator doesn't play well with boost::zip_iterator -


consider following code:

#include <boost/iterator/zip_iterator.hpp> #include <boost/range/detail/any_iterator.hpp> #include <boost/tuple/tuple.hpp> #include <iostream> #include <vector>  typedef boost::range_detail::any_iterator<   boost::tuple<int &, char &>,   boost::random_access_traversal_tag,   boost::tuple<int &, char &> &,   std::ptrdiff_t > intchariterator;  int main() {   std::vector<int> v1 = {1, 2, 3, 4, 5};   std::vector<char> v2 = {'a', 'b', 'c', 'd', 'e'};    auto = intchariterator(boost::make_zip_iterator(     boost::make_tuple(v1.begin(), v2.begin()))   );   auto end_ = intchariterator(boost::make_zip_iterator(     boost::make_tuple(v1.end(), v2.end()))   );    (; != end_; ++it)     std::cerr << it->get<0>() << " " << it->get<1>() << "\n";    return 0; } 

it works expected (i.e. prints "1 a\n2 b...") when compiled no optimizations, either segfaults or produces garbage when compiled -o2 (with both clang-3.6.0 , gcc-4.9.2, boost 1.56.0) , have no clue what's wrong.

also, when intchariterator wrapper removed, code works expected either optimization level.

does know going on here?

this bug in boost.range: #10493 since 1.56, any_range non-reference references can cause ub (warning: bug tracker has invalid ssl certificate). regression introduced fix bug #5816 any_range requires copyable elements.

the workaround, oddly enough, make reference template type parameter const:

typedef boost::range_detail::any_iterator<   boost::tuple<int &, char &>,   boost::random_access_traversal_tag,   boost::tuple<int &, char &> const,    // 'const', no '&'   std::ptrdiff_t > intchariterator; 

if want code work pre-1.56 versions can use preprocessor conditional:

typedef boost::range_detail::any_iterator<   boost::tuple<int &, char &>,   boost::random_access_traversal_tag, #if boost_version < 105600   boost::tuple<int &, char &>,          // no '&' #else   boost::tuple<int &, char &> const,    // 'const', no '&' #endif   std::ptrdiff_t > intchariterator; 

note in case reference template type parameter should not have &; per zip_iterator synopsis, reference_type same value_type, tuple of references:

typedef reference value_type; 

Comments

Popular posts from this blog

IF statement in MySQL trigger -

c++ - What does MSC in "// appease MSC" comments mean? -

javascript - Blogger related post gadget image Resize s72-c [ Need Expert Help ] -