Boost logo

Boost :

From: George A. Heintzelman (georgeh_at_[hidden])
Date: 2001-08-09 15:34:23


> string result = accumulate(strs.begin()+1, strs.end, strs.front(),
> combiner("|"));
> (the more complicated expression since we don't want the "|" if there
> is only one element);
>
> Now, what I WOULD like is an accumulate-like algorithm which takes
> functors which take the first argument as a non-const reference, and
> actually modify the first object. It needs to copy on the way in and
> the way out, but not intermediate temporaries. This would avoid a bunch
> of maybe needless copying, especially for string functions:
>
> struct combiner {
> combiner(const string &separator): mSep(separator);
> string & operator()(string &a, const string &b) {
> a += separator;
> a += b;
> return a;
> }
>
> What about LL?
>
> string result = accumulate(strs.begin() + 1, strs.end(), strs.front(),
> ll::_1 += ll::constant("|"), _a += ll::_2 );

I'm assuming you need parens to distinguish the last comma as the use
of the ll function and not a new argument... No, this won't work. The
standard says that accumulate 'Computes its result by initializing the
accumulator acc with the initial value ... and then modifying it with
... acc = binary_op1(acc, *i) for every iterator i ...'

So operator= will be called for acc multiple times (in this case,
needlessly. It *might* get optimized out, but you can't count on it).
That's what I'm trying to avoid.

The proposed new algorithm would simply call binary_op1(acc,*i) for
every iterator i, passing acc by reference and skipping the assignment,
eventually returning the accumulator. This would also allow one to
dispense with the 'Assignable' requirement for the accumulator type.

George Heintzelman
georgeh_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk