I used BOOST_FOREACH with a collection whose iterator is derived from boost::iterator_adaptor. I got this: 7>E:\boost_1_47\boost/range/iterator.hpp(63): error C2039: 'type' : is not a member of 'boost::mpl::eval_if_c<C,F1,F2>' 7> with 7> [ 7> C=true, 7> F1=boost::range_const_iterator<VSeeClient_list>, 7> F2=boost::range_mutable_iterator<const type> 7> ] 7> E:\boost_1_47\boost/foreach.hpp(670) : see reference to class template instantiation 'boost::range_iterator<C>' being compiled 7> with 7> [ 7> C=const type 7> ] 7> AutoPerformance\APSystem.cpp(224) : see reference to function template instantiation 'boost::foreach_detail_::auto_any<T> boost::foreach_detail_::begin<VSeeClient_list,boost::mpl::false_>(boost::foreach_detail_::auto_any_t,boost::foreach_detail_::type2type<VSeeClient_list,C> *,boost::mpl::false_ *)' being compiled 7> with 7> [ 7> T=VSeeClient_list::iterator, 7> C=boost::mpl::false_ 7> ] The error points here: template< typename C > struct range_iterator { typedef BOOST_RANGE_DEDUCED_TYPENAME mpl::eval_if_c< is_const<C>::value, range_const_iterator< typename remove_const<C>::type >, range_mutable_iterator<C> >::type type; }; Now a little looking through the manual tells me that mpl::eval_if_c::type will be one of the two metafunctions, so it should not disappear completely. I don't believe I missed anything from the iterator code: the Value type is given as the 3rd template argument to the iterator_adaptor, so that should set up any metafunctions needed to find the iterator's type, right? I'm compiling using MS Visual Studio 10. —John
Have you tried instantiating the range_const_iterator and range_mutable_iterator metafunctions with the relevant types and checking that they actually have ::type members? That is, do typedef range_const_iterator<your_range>::type T1; and typedef range_mutable_iterator<your_range>::type T2; compile? Regards, Nate
On 3/11/2012 6:10 AM, Nathan Ridge wrote:
Have you tried instantiating the range_const_iterator and range_mutable_iterator metafunctions with the relevant types and checking that they actually have ::type members?
That is, do
typedef range_const_iterator<your_range>::type T1;
and
typedef range_mutable_iterator<your_range>::type T2;
compile?
Regards, Nate
By 'your_range' I suppose that means the collection type I was trying to use in the FOREACH. I get an error for T1. My collection does not have a const iterator defined for it. I suppose that bothers the machinery in FOREACH even though I'm not asking for one here? —John
My collection does not have a const iterator defined for it. I suppose that bothers the machinery in FOREACH even though I'm not asking for one here?
Let's take a look at the docs. The Foreach docs say [1] that Foreach is built on top of Boost.Range, and supports types that satisfy the Single Pass Range Concept. The Boost.Range iterator docs on the Single Pass Range Concept [2] say that such ranges have associated iterator and const iterator types, accessible by boost::range_iterator<X>::type and boost::range_iterator<const X>::type, respectively. There are two methods for adapting a type to fit the Single Pass Range Concept requirement. The most commonly used method [3] is to give your range type methods named 'begin()' and 'end()' and typedefs named 'iterator' and 'const_iterator'. There is also another method suitable for cases where you cannot modify the range type [4]. So yes, if you want your range type to work with Boost.Foreach, you should employ one of those methods to make it compliant to the Single Pass Range Concept (including having a const iterator). Regards, Nate [1] http://www.boost.org/doc/libs/1_49_0/doc/html/foreach.html [2] http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/concepts/sing... [3] http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ext... [4] http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ext...
participants (2)
-
John M. Dlugosz
-
Nathan Ridge