tags:

views:

154

answers:

3

Hi! I need analog of Haskell's foldl function to fold any STL containers. Expected signature is like following:

template Iterator, FoldingFunction, Result
Result foldl(
  Iterator begin, 
  Iterator end, 
  FoldingFunction f, 
  Result initValue);

Standard STL has no such function. Does Boost have any?

I know it's pretty simple to implement, but I'd like to know whether there's any ready standardized implementation.

And one more question: how do you usually fold data lists in C++/STL?

Thanks.

+13  A: 

STL does have such a function: std::accumulate. However, it is in the header <numeric>, not <algorithm>.

Actually the Wikipedia page on "Fold" already listed the foldl/foldr functions on most programming languages, including C++.

KennyTM
@KennyTM: Especially thanks for Wiki reference.
Andrey
Note that `accumulate` uses the `value_type` of the iterator arguments for the internal accumulator variable, despite accepting and returning a distinct type, and allowing other types still in the functor argument.
Potatoswatter
@Potatoswatter: I don't see this from accumulate definition:TYPE accumulate( input_iterator start, input_iterator end, TYPE val, BinaryFunction f );
Andrey
@Andrey: Never mind. I was thinking of Defect Report 539 (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#539). `accumulate` uses the proper internal type.
Potatoswatter
+3  A: 

Have you looked at std::accumulate in the <numeric> header?

wheaties
It's `std::accumulate`. It's in the `std` namespace, but in the `<numeric>` header. :)
jalf
@jalf keep 'em coming. Only way I stay in line. :P
wheaties
A: 

Although std:: accumulate seems to be the best candidate, I think that the requirement can be achieved by using good old for_each too.

I took the examples from the link in the answer of KennyTM, and translated all of them to for_each. The full code is posted at codepad, following is some excerpt:

struct result_functor {
    result_functor( int initial, int multiplier ) :
        result_( initial ), multiplier_( multiplier ) {
    }
    int operator()( int x ) {
        result_ += multiplier_ * x;
        return result_;
    }
    int result_;
    int multiplier_;
};

const int init = 100;
const int numbers[] = { 10, 20, 30 };

const int accum_sum = std::accumulate( numbers, numbers + 3, init );
const result_functor for_sum = for_each( 
    numbers, numbers + 3, result_functor( init, +1 ) );
assert( accum_sum == for_sum.result_ );
ArunSaha