boost - 自定义迭代器不适用于 BOOST_FOREACH?

标签 boost iterator

我有一个包含一些数据的类,我想添加 begin()end()提供数据 ID 迭代器的函数。

我正在使用 Boost counting_iterator :

#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/iterator/counting_iterator.hpp>

template<class T>   
class ContainerTpl {
 public:
  typedef std::size_t Id;
  typedef boost::counting_iterator<Id> const_iterator;
  ContainerTpl() {}
  const_iterator begin() {
    return boost::counting_iterator<Id>(0);
  }
  const_iterator end() {
    return boost::counting_iterator<Id>(container_.size());
  }
 private:
  std::vector<T> container_;
};

int main () {
  typedef ContainerTpl<double> Container;
  Container c;
  BOOST_FOREACH (Container::Id cid, c) {
    std::cerr << cid << std::endl;
  }
  return 0;
}

请注意,这是最小的示例代码;实际上,该类包含更多功能,例如,一个 typedefvector将是不够的。我真的需要那个带有 ID 迭代器的类。

不幸的是,上面的代码给了我非常讨厌的编译器错误:
In file included from boost/foreach.hpp:71,
                 from a.cpp:3:
boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if<mpl_::bool_<false>, boost::range_const_iterator<ContainerTpl<double> >, boost::range_mutable_iterator<ContainerTpl<double> > >’:
boost/foreach.hpp:355:   instantiated from ‘boost::foreach_detail_::foreach_iterator<ContainerTpl<double>, mpl_::bool_<false> >’
a.cpp:25:   instantiated from here
boost/mpl/eval_if.hpp:38: error: no type named ‘type’ in ‘struct boost::range_mutable_iterator<ContainerTpl<double> >’
a.cpp: In function ‘int main()’:
a.cpp:25: error: no matching function for call to ‘begin(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*, boost::mpl::o\
r_<boost::mpl::and_<boost::mpl::not_<boost::is_array<ContainerTpl<double> > >, mpl_::bool_<false>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, boost::mpl::and_<boost::mpl::not_<boo\
st::foreach::is_noncopyable<ContainerTpl<double> > >, boost::foreach::is_lightweight_proxy<ContainerTpl<double> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, mpl_::bool_<false>, m\
pl_::bool_<false>, mpl_::bool_<false> >*)’
a.cpp:25: error: no matching function for call to ‘end(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*, boost::mpl::or_\
<boost::mpl::and_<boost::mpl::not_<boost::is_array<ContainerTpl<double> > >, mpl_::bool_<false>, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, boost::mpl::and_<boost::mpl::not_<boost\
::foreach::is_noncopyable<ContainerTpl<double> > >, boost::foreach::is_lightweight_proxy<ContainerTpl<double> >, mpl_::bool_<true>, mpl_::bool_<true>, mpl_::bool_<true> >, mpl_::bool_<false>, mpl\
_::bool_<false>, mpl_::bool_<false> >*)’
a.cpp:25: error: no matching function for call to ‘deref(const boost::foreach_detail_::auto_any_base&, boost::foreach_detail_::type2type<ContainerTpl<double>, mpl_::bool_<false> >*)’

我怎样才能使代码工作?

更新:根据答案,我添加了以下代码,使其工作:
namespace boost
{
// specialize range_mutable_iterator and range_const_iterator in                                                                                                                                    
// namespace boost                                                                                                                                                                                  
template<class T>
struct range_mutable_iterator< ContainerTpl<T> > {
  typedef typename ContainerTpl<T>::const_iterator type;
};

template<class T>
struct range_const_iterator< ContainerTpl<T> > {
  typedef typename ContainerTpl<T>::const_iterator type;
};
} // end namespace         

最佳答案

Boost 文档中有一个关于此的页面:

http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/foreach/extensibility.html

总之你需要定义 boost::range_mutable_iterator<>为您的类型,以便编译器可以实例化模板类型 BOOST_FOREACH正在尝试使用。

为 future 的谷歌员工编辑:

我不确定那个“沙箱”URL 是否总是指向最新版本,或者是一个最终会中断的临时位置。这是当前版本的链接,它可能更稳定,但会过时:

http://www.boost.org/doc/libs/1_50_0/doc/html/foreach/extensibility.html

关于boost - 自定义迭代器不适用于 BOOST_FOREACH?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5863805/

相关文章:

c++ - Boost::asio 和嵌套/递归 service.run()/run_one()

Java:优先级队列实现可按正确顺序迭代

c++ - 在循环缓冲区中存储结构数据

c++ - 如何将 boost::exception 与 boost::unit_test 结合起来,并有一个很好的消息

c++ - 努力创建包含 std::bitset 的 Boost-Bimap

c++ - 如何有效地使用 boost::process::async_pipe 进行写入和读取?

php - 关联数组的下一个迭代器方法

c++ - 如何消除此枚举到字符串映射代码的样板?

python - 运行时错误 : dictionary changed size during iteration - During Iteration with iteritems on a defaultdict

c++ - 返回在 C++ 中没有 back() 方法的容器的最后一个元素?