boost::range::d etail::any_iterator 不能很好地与 boost::zip_iterator 一起使用



考虑以下代码:

#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 it = 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()))
  );
  for (; it != end_; ++it)
    std::cerr << it->get<0>() << " " << it->get<1>() << "n";
  return 0;
}

它可以按预期(即打印" 1 a n2 b ...")进行编译而没有优化,但是使用-O2编译时segfaults或产生垃圾(带有clang-3.6.0和GCC-4.9.2,提升1.56.0),我不知道怎么了。

另外,当删除Intchariterator包装器时,该代码按预期工作,以任意优化级别。

有人知道这里发生了什么吗?

这是boost.range:#10493 以来的错误无效的SSL证书)。这是Fix for Bug#5816 any_range引入的回归,需要可复制的元素

奇怪的是,解决方法是使您的Reference模板类型参数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;

如果您希望代码与1.56版本一起使用,则可以使用预处理器条件:

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;

请注意,在任何情况下,Reference模板类型参数应该具有&;根据zip_iterator概述,reference_typevalue_type相同,因为它是参考的元组:

typedef reference value_type;

最新更新