
A recent post in this list started me thinking... Given this code snippet, using namespace std; void f( int, int ); vector<int> v1; vector<int> v2; // populate... for ( unsigned i = 0; i <= v1.size( ); ++ i ) { f( v1[ i ], v2[ i ] ); } How would you write this as a for_each() or in some other Boosty, functional way? (The aspect I'm trying to highlight is that two iterators over different ranges must advance in step) One could imagine a tuple-based solution, in which one specifies how an operation applied to the tuple distributes to operations applied to each of the tuple's elements. Does any such thing exist in Boost? Is it ever necessary, or can the functionality be achieved by some C++/STL/Boost idiom that I've not thought of? If there is no obvious technique, is there any interest in a Boost library which address this in a generic way? Thanks. - Rob.

Robert Jones wrote:
A recent post in this list started me thinking...
Given this code snippet,
using namespace std;
void f( int, int );
vector<int> v1; vector<int> v2;
// populate...
for ( unsigned i = 0; i <= v1.size( ); ++ i ) { f( v1[ i ], v2[ i ] ); }
How would you write this as a for_each() or in some other Boosty, functional way? (The aspect I'm trying to highlight is that two iterators over different ranges must advance in step)
One could imagine a tuple-based solution, in which one specifies how an operation applied to the tuple distributes to operations applied to each of the tuple's elements.
Does any such thing exist in Boost? Is it ever necessary, or can the functionality be achieved by some C++/STL/Boost idiom that I've not thought of?
If there is no obvious technique, is there any interest in a Boost library which address this in a generic way?
Thanks.
- Rob.
The tuple-based solution seems elegant if you have a varying number of ranges. For your two ranges requirement, a simple custom writing of a for_each would do, like this: template<class ForwardIterator, class ForwardIterator2, Class Op> Op for_each(ForwardIterator first, ForwardIterator last, ForwardIterator2 first2, Op op){ for(;first != last; ++first, ++first2) op(*(first), *(first2)); return (op); } Does this work for you?

On Fri, Oct 24, 2008 at 9:56 AM, <mbiddeg@mtn.co.ug> wrote:
The tuple-based solution seems elegant if you have a varying number of ranges. For your two ranges requirement, a simple custom writing of a for_each would do, like this:
template<class ForwardIterator, class ForwardIterator2, Class Op> Op for_each(ForwardIterator first, ForwardIterator last, ForwardIterator2 first2, Op op){
for(;first != last; ++first, ++first2) op(*(first), *(first2));
return (op);
}
Does this work for you?
I was thinking more of the general case, rather than two ranges specifically. However I do appreciate that for simple cases the simple solution is often the best, as it probably would be here. Many Thanks. - Rob.

On Fri, Oct 24, 2008 at 1:32 AM, Robert Jones <robertgbjones@gmail.com> wrote:
void f( int, int );
vector<int> v1; vector<int> v2;
// populate...
for ( unsigned i = 0; i <= v1.size( ); ++ i ) { f( v1[ i ], v2[ i ] ); }
How would you write this as a for_each() or in some other Boosty, functional way?
The following page seems to have a related example: http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/zip_iterator.html Is that what you were looking for? Stjepan

On Fri, Oct 24, 2008 at 9:59 AM, Stjepan Rajko <stipe@asu.edu> wrote:
The following page seems to have a related example: http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/zip_iterator.html
Is that what you were looking for?
Yep, that's what I was looking for! Spot-on, I can see this has already been done. Another great idea bites the dust - I'm too late as usual! Thanks, Rob.

Robert Jones wrote:
On Fri, Oct 24, 2008 at 9:59 AM, Stjepan Rajko <stipe@asu.edu> wrote:
The following page seems to have a related example: http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/zip_iterator.html
Is that what you were looking for?
Yep, that's what I was looking for! Spot-on, I can see this has already been done. Another great idea bites the dust - I'm too late as usual!
What would be useful is a generic function object whose argument is the tuple from above and can forward to a supplied function whose arguments are the individual values from the tuple. Something that keeps me from littering my code with custom functions ala: void existing_function(const T1&, const T2&, const T3&); struct tuple_adaptation_of_existing_function { void operator()(const tuple<T1, T2, T3>& t) const { existing_function(get<0>(t), get<1>(t), get<2>(t)); } }; Jeff

Jeff Flinn wrote:
What would be useful is a generic function object whose argument is the tuple from above and can forward to a supplied function whose arguments are the individual values from the tuple.
Something that keeps me from littering my code with custom functions ala:
void existing_function(const T1&, const T2&, const T3&);
struct tuple_adaptation_of_existing_function { void operator()(const tuple<T1, T2, T3>& t) const { existing_function(get<0>(t), get<1>(t), get<2>(t)); } };
Yep. Boost.Fusion has several such utilities ... http://www.boost.org/doc/libs/1_36_0/libs/fusion/doc/html/fusion/functional/... -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Jeff Flinn wrote:
What would be useful is a generic function object whose argument is the tuple from above and can forward to a supplied function whose arguments are the individual values from the tuple.
Something that keeps me from littering my code with custom functions ala:
void existing_function(const T1&, const T2&, const T3&);
struct tuple_adaptation_of_existing_function { void operator()(const tuple<T1, T2, T3>& t) const { existing_function(get<0>(t), get<1>(t), get<2>(t)); } };
Yep. Boost.Fusion has several such utilities ...
http://www.boost.org/doc/libs/1_36_0/libs/fusion/doc/html/fusion/functional/...
Thanks Eric, I'll take a look. Jeff
participants (5)
-
Eric Niebler
-
Jeff Flinn
-
mbiddeg@mtn.co.ug
-
Robert Jones
-
Stjepan Rajko