Hi I'm trying to use make_indirect_iterator on a container of shared_ptrs as follows: #include <boost/iterator_adaptors.hpp> #include <boost/shared_ptr.hpp> #include <list> #include <algorithm> #include <functional> using std::mem_fun_ref; using std::mem_fun; using std::list; using boost::shared_ptr; using std::for_each; using boost::make_indirect_iterator; class A { public: void f(){} }; int main() { list<A *> List1; list<shared_ptr<A> > List2; // This works for_each(make_indirect_iterator(List1.begin()), make_indirect_iterator(List1.end()), mem_fun_ref(&A::f)); // This doesn't work for_each(make_indirect_iterator(List2.begin()), make_indirect_iterator(List2.end()), mem_fun_ref(&A::f)); } The second use of for each fails to compile (error messages at the end of the message). Is it possible to do this? Am I doing something wrong? I'm using gcc v 2.95.2. and the QNX OS. Thanks Richard QCC -I/home/rwolf/boat/src/includes -I/home/rwolf/boat/src/boost_1_27_0 -Wal l -L/home/rwolf/boat/src/lib -L. -O -g -I/home/rwolf/boat/src/includes -I/h ome/rwolf/boat/src/boost_1_27_0 -Wall test.cpp -o test /usr/include/xutility: In instantiation of `std::iterator_traits<boost::shared_ptr<A> >': /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1104: instantiated from `boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::all ocator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: instantiated from here /usr/include/xutility:81: no type named `iterator_category' in `class boost::shared_ptr<A>' /usr/include/xutility:82: no type named `value_type' in `class boost::shared_ptr<A>' /usr/include/xutility:83: no type named `difference_type' in `class boost::shared_ptr<A>' /usr/include/xutility:84: no type named `difference_type' in `class boost::shared_ptr<A>' /usr/include/xutility:85: no type named `pointer' in `class boost::shared_ptr<A>' /usr/include/xutility:86: no type named `reference' in `class boost::shared_ptr<A>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp: In instantiation of `boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::all ocator<boost::shared_ptr<A> > >::iterator>': /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: instantiated from here /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1104: no type named `value_type' in `struct std::iterator_traits<boost::shared_ptr<A> >' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1105: no type named `reference' in `struct std::iterator_traits<boost::shared_ptr<A> >' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1106: no type named `pointer' in `struct std::iterator_traits<boost::shared_ptr<A> >' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp: In function `int main()': /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `value_type' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `reference' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `pointer' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 2 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 3 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 5 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp: At top level: /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp: In instantiation of `boost::make_indirect_iterator<std::list<boost::shared_ptr<A>,std::allocator <boost::shared_ptr<A> > >::iterator>(...)': test.cpp:26: instantiated from here /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `value_type' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `reference' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: no type named `pointer' in `struct boost::detail::traits_of_value_type<std::list<boost::shared_ptr<A>,std::allo cator<boost::shared_ptr<A> > >::iterator>' /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 2 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 3 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: template argument 5 is invalid /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp: In function `{error} boost::make_indirect_iterator<std::list<boost::shared_ptr<A>,std::allocator< boost::shared_ptr<A> > >::iterator>(...)': /home/rwolf/boat/src/boost_1_27_0/boost/iterator_adaptors.hpp:1177: confused by earlier errors, bailing out cc: /usr/lib/gcc-lib/ntox86/2.95.2/cc1plus error 34 make: *** [test] Error 1
From: "Richard Wolf" <richard@student.usyd.edu.au>
Hi
I'm trying to use make_indirect_iterator on a container of shared_ptrs as follows:
[...]
int main() { list<shared_ptr<A> > List2;
// This doesn't work for_each(make_indirect_iterator(List2.begin()), make_indirect_iterator(List2.end()), mem_fun_ref(&A::f)); }
The reason is that make_indirect_iterator tries to instantiate std::iterator_traits< shared_ptr<A> >, and this fails, because shared_ptr<A> is not an iterator. You can make the for_each work by using for_each(List2.begin(), List2.end(), boost::mem_fn(&A::f)); // in <boost/mem_fn.hpp> if that's what you want.
----- Original Message ----- From: "Peter Dimov" <pdimov@mmltd.net> To: <Boost-Users@yahoogroups.com> Sent: Thursday, August 29, 2002 12:17 AM Subject: Re: [Boost-Users] shared_ptr and make_indirect_iterator
From: "Richard Wolf" <richard@student.usyd.edu.au>
Hi
I'm trying to use make_indirect_iterator on a container of shared_ptrs as follows:
[...]
int main() { list<shared_ptr<A> > List2;
// This doesn't work for_each(make_indirect_iterator(List2.begin()), make_indirect_iterator(List2.end()), mem_fun_ref(&A::f)); }
The reason is that make_indirect_iterator tries to instantiate std::iterator_traits< shared_ptr<A> >, and this fails, because shared_ptr<A> is not an iterator.
You can make the for_each work by using
for_each(List2.begin(), List2.end(), boost::mem_fn(&A::f)); // in <boost/mem_fn.hpp>
if that's what you want.
Thank you. I suppose this means that the container must contain a type that is an iterator rather than a pointer. A raw pointer works because raw pointers are iterators. But.... The documentation of Indirect Iterator Adapter says : "The indirect iterator adaptor augments an iterator by applying an extra dereference inside of operator*(). For example, this iterator makes it possible to view a container of pointers or smart-pointers (e.g. std::list<boost::shared_ptr<foo> >) as if it were a container of the pointed-to type." Is the documentation incorrect, or have I misunderstood? Thanks Richard
From: "Richard Wolf" <richard@student.usyd.edu.au>
Thank you. I suppose this means that the container must contain a type
that
is an iterator rather than a pointer. A raw pointer works because raw pointers are iterators. But....
The documentation of Indirect Iterator Adapter says :
"The indirect iterator adaptor augments an iterator by applying an extra dereference inside of operator*(). For example, this iterator makes it possible to view a container of pointers or smart-pointers (e.g. std::list<boost::shared_ptr<foo> >) as if it were a container of the pointed-to type."
Is the documentation incorrect, or have I misunderstood?
This has been discussed in the past on the [boost] list, see http://lists.boost.org/MailArchives/boost/msg33264.php In short, the claim is that the documentation is correct since it's possible to make an indirect iterator that will work; it's just that make_indirect_iterator cannot be used for that. I have since added ::value_type to shared_ptr, but unfortunately, this is apparently not enough. Even though the indirect iterator adaptor needs only the value_type, the attempt to instantiate std::iterator_traits means that make_indirect_iterator cannot work with shared_ptr.
From: "Richard Wolf" <richard@student.usyd.edu.au>
Thank you. I suppose this means that the container must contain a type
that
is an iterator rather than a pointer. A raw pointer works because raw pointers are iterators. But....
The documentation of Indirect Iterator Adapter says :
"The indirect iterator adaptor augments an iterator by applying an extra dereference inside of operator*(). For example, this iterator makes it possible to view a container of pointers or smart-pointers (e.g. std::list<boost::shared_ptr<foo> >) as if it were a container of the pointed-to type."
Is the documentation incorrect, or have I misunderstood?
This has been discussed in the past on the [boost] list, see
http://lists.boost.org/MailArchives/boost/msg33264.php
In short, the claim is that the documentation is correct since it's
"Peter Dimov" <pdimov@mmltd.net> wrote in message news:00ce01c24f65$03862790$1d00a8c0@pdimov2... possible
to make an indirect iterator that will work; it's just that make_indirect_iterator cannot be used for that.
I have since added ::value_type to shared_ptr, but unfortunately, this is apparently not enough. Even though the indirect iterator adaptor needs only the value_type, the attempt to instantiate std::iterator_traits means that make_indirect_iterator cannot work with shared_ptr.
Why is that? There's no reason that instantiating std::iterator_traits<shared_ptr<T> > should cause a problem by itself. -- ----------------------------------------------------------- David Abrahams * Boost Consulting dave@boost-consulting.com * http://www.boost-consulting.com
"Peter Dimov" <pdimov@mmltd.net> wrote in message news:00ce01c24f65$03862790$1d00a8c0@pdimov2...
I have since added ::value_type to shared_ptr, but unfortunately, this
is
apparently not enough. Even though the indirect iterator adaptor needs only the value_type, the attempt to instantiate std::iterator_traits means
From: "David Abrahams" <yg-boost-users@gmane.org> that
make_indirect_iterator cannot work with shared_ptr.
Why is that? There's no reason that instantiating std::iterator_traits<shared_ptr<T> > should cause a problem by itself.
Try it: #include <boost/shared_ptr.hpp> #include <iterator> int main() { std::iterator_traits< boost::shared_ptr<int> >::value_type i = 0; } When you instantiate iterator_traits, all of its typedefs are instantiated.
participants (3)
-
David Abrahams
-
Peter Dimov
-
Richard Wolf