I have a class that contains some data, and I would like to add the begin() and end() functions that provide iterators over the data identifiers.
I am using 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; }
Please note that this is the minimum sample code; in fact, the class contains more functionality, so, for example, from typedef to vector will not be enough. I really need this class with an iterator over identifiers.
Unfortunately, the above code gives me some pretty nasty compiler errors:
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> >*)'
How can I make the code work?
UPDATE: after the response, add the following code that makes it work:
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; }; }