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
Post a Comment