454,344 Members | 1,853 Online Need help? Post your question and get tips & solutions from a community of 454,344 IT Pros & Developers. It's quick & easy.

# for_each with vector of function objects

 P: n/a I have a vector of N values and a vector of N functors. I want to apply each functor to its corresponding value. What would be the 'correct' STL way to do this. for_each takes on functor and applies it to every element. So presumably transform is a better option but it also takes one functor. This is obviously easily solved by a variety of methods but I am interested in how the STL would best solve this problem. e.g. // fill vector with some values vector
6 Replies

 P: n/a al*************@gmail.com wrote: I have a vector of N values and a vector of N functors. I want to apply each functor to its corresponding value. What would be the 'correct' STL way to do this. for_each takes on functor and applies it to every element. So presumably transform is a better option but it also takes one functor. This is obviously easily solved by a variety of methods but I am interested in how the STL would best solve this problem. e.g. // fill vector with some values vector void apply(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) { while (first1 != last1 && first2 != last2) (*first1++)(*first2++); } and you'd call it like this: apply(funcs.begin(), funcs.end(), x.begin(), x.end()); Or, if the only reason you copied values in the first place was to get the contents into a vector, you can skip that copy and pass the values iterators: apply(funcs.begin(), funcs.end(), values.begin(), values.end()); -- -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference." (www.petebecker.com/tr1book) Nov 14 '06 #2

 P: n/a In article <11**********************@h48g2000cwc.googlegroups .com>, al*************@gmail.com wrote: I have a vector of N values and a vector of N functors. I want to apply each functor to its corresponding value. What would be the 'correct' STL way to do this. for_each takes on functor and applies it to every element. So presumably transform is a better option but it also takes one functor. This is obviously easily solved by a variety of methods but I am interested in how the STL would best solve this problem. e.g. // fill vector with some values vector

 P: n/a Pete Becker wrote: I'd write the explicit loop. But if you want to write a template that takes iterators, it would be something like this: template void apply(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) { while (first1 != last1 && first2 != last2) (*first1++)(*first2++); } Do you need to increment both? transform that takes 2 inputs only increments one and relies on "UB" if the unchecked sequence is shorter than the first. (It can be longer, it simply runs for the length of the checked sequence). Also although it can be written in one line, I think it's better to use pre-increment because it avoids a copy of the iterator, and you don't know how expensive that might be from a template. Although it is more lines in your code, I don't see that it will generate more lines of object code. So how about: template< typename Iter1, typename Iter2 > void apply( Iter1 first1, Iter1 last1, Iter2 first2 ) { while ( first1 != last1 ) { (*first1)(*first2); ++first1; ++first2; } } and you'd call it like this: apply(funcs.begin(), funcs.end(), x.begin(), x.end()); In my example no x.end(), just the first 3 parameters. Nov 14 '06 #4

 P: n/a Daniel T. wrote: > There is a transform that takes iterators into two containers, but it assumes that the functions will produce outputs and you don't seem to be doing that. As such, I agree with Pete's post. To use that you'd have to write a non-iterator for the output, and the operator that takes the 2 parameters would get the functor to invoke on the object. Easier to write the algorithm, but if we really want to use transform: iterator: all of the operators (++, *, =) will do nothing. operator=() could be a template because it does nothing with its parameter anyway. Not sure what you'd do with the typedefs if we really need them anyway. operator: struct call_func { template < typename F, typename P > void operator() ( F func, P param ) { func( param ); } }; The final way is to use for_each and get the functor to store the beginning of one sequence. Let's say it stores the functors. Again it could store an iterator. template < typename FuncIterator > struct FunctorFunctor { private: FuncIterator func_iter; public: explicit FunctorFunctor( FuncIterator fi ) : func_iter ( fi ) {} template < typename T > void operator() ( T t ) { (*func_iter)( t ); ++func_iter; } }; template< typename FuncIterator > FunctorFunctor< FuncIterator functor_functor( FuncIterator fi ) { return FunctorFunctor< FuncIterator >( fi ); } Nov 14 '06 #5

 P: n/a Ok, the solution is to write my own STL like function. I like the apply idea. If I were to return values from the function and store these in a result vector then I could use transform a la: transform (values.begin(), values.end(), functors.begin(), results.begin(), my_apply()); where: struct my_apply { template< typename T, typename F > T operator()(T& x, F& f) { return f(x); } }; Does this work with boost::lambda? transform (values.begin(), values.end(), functors.begin(), results.begin(), _2(_1) ); Thanks, Alan On Nov 14, 4:00 pm, "Daniel T." , alan.patters...@gmail.com wrote: I have a vector of N values and a vector of N functors. I want to apply each functor to its corresponding value. What would be the 'correct' STL way to do this. for_each takes on functor and applies it to every element. So presumably transform is a better option but it also takes one functor. This is obviously easily solved by a variety of methods but I am interested in how the STL would best solve this problem. e.g. // fill vector with some values vector

 P: n/a Earl Purple wrote: Pete Becker wrote: >I'd write the explicit loop. But if you want to write a template thattakes iterators, it would be something like this:template void apply(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2){while (first1 != last1 && first2 != last2) (*first1++)(*first2++);} Do you need to increment both? Yes, you need to increment both. If you like, you can skip the second comparison, but the information is there, so why not use it? transform that takes 2 inputs only increments one and relies on "UB" if the unchecked sequence is shorter than the first. It doesn't rely on UB. In fact, I'm not even sure what that means. It says that the behavior is undefined if the second sequence is too short. > Also although it can be written in one line, I think it's better to use pre-increment because it avoids a copy of the iterator, and you don't know how expensive that might be from a template. Although it is more lines in your code, I don't see that it will generate more lines of object code. So how about: template< typename Iter1, typename Iter2 > void apply( Iter1 first1, Iter1 last1, Iter2 first2 ) { while ( first1 != last1 ) { (*first1)(*first2); ++first1; ++first2; } } Write it however you like. -- -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference." (www.petebecker.com/tr1book) Nov 14 '06 #7

### This discussion thread is closed

Replies have been disabled for this discussion. 