Re: [Boost-users] Iterating over the seconds of a list of pairs

-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Björn Karlsson Sent: 08 August 2009 18:12 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Iterating over the seconds of a list of pairs
You're right -- transform_iterator is the right tool for the job. Try something like this.
1) Write a function object that extracts the second element of the pair. 2) Use the transform iterator adaptor to provide you with the type of the iterators for your class. 3) Use the helper function make_transform_iterator in your begin() and end() methods to create the iterators.
Here's an example that does the above:
#include <iostream> #include <list> #include <utility>
#include "boost/iterator/transform_iterator.hpp"
// Extract the second element of a pair template <typename T> class pair_second_t { public: typedef T result_type;
template <typename U> T operator()(const std::pair<U,T>& element) const { return element.second; } };
class some_class { public: typedef std::list<std::pair<double,float> > container_type; typedef boost::transform_iterator<pair_second_t<float>, container_type::iterator> iterator_type; Bjorn Karlsson
Hello bjorn, I have a similar problem. I have a vector< pair<LeftT, RightT> >. I'm very happy to use vector< pair<LeftT, RightT> >::iterator The only extra is I'd like to name the functions GetLeft() and GetRight() and make them callable as: typedef vector< pair<LeftT, RightT> >::iterator stl_iterator; stl_iterator i = ...; i->GetLeft() and i->GetRight() // I can't do this obviously so: typedef boost::transform_iterator<functor, stl_iterator> my_iterator_type; Should functor provide GetLeft() and GetRight()? or should my_iterator_type derive from the result of transform_iterator<functor, stl_iterator> ? regards,

Hello Hicham,
I have a similar problem. I have a vector< pair<LeftT, RightT> >. I'm very happy to use vector< pair<LeftT, RightT> >::iterator
The only extra is I'd like to name the functions GetLeft() and GetRight() and make them callable as:
typedef vector< pair<LeftT, RightT> >::iterator stl_iterator; stl_iterator i = ...; i->GetLeft() and i->GetRight() // I can't do this obviously
You could inherit from std::pair and add the member functions GetLeft() and GetRight() to your derived class. Or implement your pair from scratch, naming the members according to your domain.
so: typedef boost::transform_iterator<functor, stl_iterator> my_iterator_type;
Should functor provide GetLeft() and GetRight()? or should my_iterator_type derive from the result of transform_iterator<functor, stl_iterator> ?
It's technically possible to use transform_iterator for what you want, but it's much too complicated for just the convenience of those two additional member functions. Free functions would be cleaner, easier, and almost as convenient for your users: template <typename T, typename U> T& GetLeft(std::pair<T,U>& p) { return p.first; } template <typename T, typename U> const T& GetLeft(const std::pair<T,U>& p) { return p.first; } With that, you can write code like: iterator it = container.begin(); GetLeft(*it); If you really, really, really want to go through the trouble of adding GetLeft() and GetRight() using transform_iterator, you can do this: 1) Write a class that stores a reference to a pair and implements GetLeft() and GetRight() to return pair::first and pair::second, respectively. 2) Write a function object that returns an instance of the class from 1) in the function call operator (taking one argument that is a reference to a pair). The function call operator need to be declared const, and you'll need a typedef for result_type that is the class from 1). 3) Use the function object in 2) as the unary function for transform_iterator. But if you're willing to go through all of that trouble it's much better to go with the derived class -- less work, probably more efficient, and definitely more maintainable. I only mention the above because there might be other use cases (such as when implementing the Adapter pattern) when it actually makes sense to do something like that. However, I have yet to see a real-world scenario for that. (Since I don't recommend the technique for this issue, I won't attach sample code...) Does that help? Cheers, Bjorn Karlsson www.skeletonsoftware.net
participants (2)
-
Björn Karlsson
-
Hicham Mouline