Range for STL containers

I use heavy BOOST_FOREACH to iterate over containers, and since I moved to C ++ 0x recently, I decided to replace BOOST_FOREACH with a BOOST_FOREACH based for construct. The following code snippet

 #include<vector> #include<boost/shared_ptr.hpp> #include<boost/range.hpp> using std::vector; using boost::shared_ptr; class Node; int main(void){ vector<shared_ptr<Node>> nodes; for(const shared_ptr<Node>& n: nodes); } 

fails to compile with gcc 4.6, resulting in

 error: call of overloaded 'end(std::vector<boost::shared_ptr<Node> >&)' is ambiguous note: candidates are: /usr/include/c++/4.6/bits/range_access.h:78:5: note: decltype (__cont->end()) std::end(const _Container&) [with _Container = std::vector<boost::shared_ptr<Node> >, decltype (__cont->end()) = __gnu_cxx::__normal_iterator<const boost::shared_ptr<Node>*, std::vector<boost::shared_ptr<Node> > >] /usr/include/c++/4.6/bits/range_access.h:68:5: note: decltype (__cont->end()) std::end(_Container&) [with _Container = std::vector<boost::shared_ptr<Node> >, decltype (__cont->end()) = __gnu_cxx::__normal_iterator<boost::shared_ptr<Node>*, std::vector<boost::shared_ptr<Node> > >] /usr/include/boost/range/end.hpp:103:47: note: typename boost::range_iterator<const T>::type boost::end(const T&) [with T = std::vector<boost::shared_ptr<Node> >, typename boost::range_iterator<const T>::type = __gnu_cxx::__normal_iterator<const boost::shared_ptr<Node>*, std::vector<boost::shared_ptr<Node> > >] /usr/include/boost/range/end.hpp:92:41: note: typename boost::range_iterator<C>::type boost::end(T&) [with T = std::vector<boost::shared_ptr<Node> >, typename boost::range_iterator<C>::type = __gnu_cxx::__normal_iterator<boost::shared_ptr<Node>*, std::vector<boost::shared_ptr<Node> > >] 

Is there a way to avoid such ambiguity or to be range-based simply unsuitable for use in such a situation?

+4
source share
1 answer

Tricky You pull std::end and boost::end because the corresponding namespaces std::vector<boost::shared_ptr> are equal to std and boost . Both are patterns that match.

However, a non-pattern end() would be an even better match. So just specify your own:

 inline std::vector<boost::shared_ptr<Node> >::iterator end(std::vector<boost::shared_ptr<Node> > vsn&) { return std::end(vsn); } 
+3
source

All Articles