range-based for on STL containers
I am using heavily BOOST_FOREACH
for iteration over containers, and since I moved to c++0x recently, I thought I could replace BOOST_FOREACH
with range-based for
construct. The following piece of code
#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);
}
does not compile with gcc
4.6, leading to
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 is range-based for simply unusable in such situation?
Tricky. You're pulling in std::end
and boost::end
because the associated namespaces of std::vector<boost::shared_ptr>
are both std
and boost
. Both are templates that match.
However, a non-template end()
would be an even better match. So, just provide your own:
inline std::vector<boost::shared_ptr<Node> >::iterator
end(std::vector<boost::shared_ptr<Node> > vsn&)
{
return std::end(vsn);
}
精彩评论