我有一个包含一些数据的类,我想添加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;
}
请注意,这是最小的示例代码;实际上,该类包含更多功能,因此,例如,typedef
到vector
是不够的。我真的需要那个类,带有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
答案 0 :(得分:8)
Boost文档中有一个关于此的页面:
http://boost-sandbox.sourceforge.net/libs/foreach/doc/html/foreach/extensibility.html
简而言之,您需要为您的类型定义boost::range_mutable_iterator<>
,以便编译器可以实例化BOOST_FOREACH
尝试使用的模板类型。
编辑未来的googlers:
我不确定该“沙箱”网址是否始终指向最新版本,或者是一个最终会破坏的临时位置。这是当前版本的链接,可能更稳定,但它会过时:
http://www.boost.org/doc/libs/1_50_0/doc/html/foreach/extensibility.html
答案 1 :(得分:2)
我知道这是一个老问题,但似乎仍然相关。我有这个问题,并注意到boost foreach要求你有一个可变的迭代器,以及一个const_iterator定义(所以,ContainerTpl :: iterator和ContainerTpl :: const_iterator)。如果不这样做,你需要按照Tim提供的说明进行操作。