HyunSangTae
HyunSangTae

Reputation: 43

C++ functor unexpected behavior in for_each

Consider the following example:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class accum
{
public:
    int sum;
    accum()
    {
        sum = 0;
    }
    void operator() (int a)
    {
        sum += a;
        printf("sum=%d\n",sum);
    }
};

int main()
{
     int ari[] = {2,8,5,9,1};
     vector<int> vi(&ari[0], &ari[5]);
     accum f;
     for_each(vi.begin(), vi.end(), f);
     printf("final sum : %d\n", f.sum);
}

I expected the sum to be 25, but it prints 0. Why does f remain unchanged? Can somebody give me a detailed account of what is going on?

Upvotes: 4

Views: 76

Answers (1)

Barry
Barry

Reputation: 303057

That's because std::for_each takes its functor by value, not by reference. It's operating internally on a copy of f and the one you pass in remains unchanged. It does return the functor back to you, so you could just overwrite yours:

accum f = std::for_each(vi.begin(), vi.end(), accum());

Or, sticking with C++03, have accum take a reference:

struct accum {
    int& sum;
    // rest as before, fixing the constructor
};

int sum = 0;
std::for_each(vi.begin(), vi.end(), accum(sum));
printf("final sum : %d\n", sum);

Although perhaps you might just want std::accumulate:

int sum = std::accumulate(vi.begin(), vi.end(), 0);

Or, in C++11, for_each with a lambda:

int sum = 0;
std::for_each(vi.begin(), vi.end(), [&](int a){ sum += a; });

Upvotes: 5

Related Questions