On Friday 14 December 2001 03:06 pm, you wrote:
Hello,
I'm trying to explore the compose, bind, and mem_fn libraries. I used a "real" problem I'm having. Given a vector<Trade>, I want to gather a sum of the return values of Trade::volume(). [...] vector<Trade> li; // ..... sum = accumulate_with_op(li.begin(),li.end(),0,mem_fun_ref (&Trade::volume))
This gives me my sum pretty nicely, so I'm sort of happy... BUT...
Here are two ways to compute the sum without defining your own functions or classes. Both methods use std::accumulate (which, of course, is what you're trying to do), but the difference is in the way that Trade::volume() is called. The first code snippet uses Boost.Bind only. We essentially create a function object that takes two arguments, x and y, and then performs the operation x + y.Volume(). We get '+' by using the standard library's plus<int>, and we use the fact that bind is composable to call Volume on the second argument. The code is thus: std::accumulate(li.begin(), li.end(), 0, boost::bind<int>( std::plus<int>(), _1, boost::bind(&Trade::Volume, _2))); The other option is philosophically different. Instead of transforming he values as we add them, we instead transform the sequence we are adding using the Boost Iterator Adaptors library. The transform_iterator adapts an iterator by applying a function object to each element as it is dereferenced. Therefore, the sequence that accumulate "sees" is the result of calling Trade::Volume on each member of the underlying sequence. Here's the code: std::accumulate( boost::make_transform_iterator(li.begin(), boost::mem_fn(&Trade::Volume)), boost::make_transform_iterator(li.end(), boost::mem_fn(&Trade::Volume)), 0); I consider this version better (philosphically) because the accumulation is over things we can actually accumulate - integers. The transform_iterator version is also more reusable code, because now you have the ability to transform a sequence of Trade objects (or Trade object pointers - see the documentation of mem_fn) into their corresponding trade volumes, and other operations become simpler. Code was tested under GCC 2.95.3, but I expect it will work for MSVC5. Doug