#include <iostream>
#include <algorithm>
#include <vector>
usingnamespace std;
class Sum
{
int t;
public:
Sum(int i):t(i){}
voidoperator()(int a)
{
t+=a;
cout <<"(a)" << a << "| t = " << t << endl; //trace the t value
}
int result()
{
return t; //to return object value
}
};
int main()
{
vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
Sum sum(0);
for_each(vi.begin(),vi.end(),sum);
cout <<"Sum result: " <<sum.result() << endl;
}
result is: (a)1| t = 1
(a)2| t = 3
(a)3| t = 6
Sum result: 0
I expect the last line to return result 6 but it is 0.
I traced the processing in for_each() function, it seems work but it does not give me correct result.
My advice is to use std::accumulate(), which does exactly what you need with no need for
a function object.
std::cout << "The sum is " << std::accumulate( vi.begin(), vi.end(), 0 ) << std::endl;
As for what's wrong with your code: the problem is that the function object you pass to
std::for_each cannot maintain state per the STL requirements because std::for_each
will make a copy of the object to call operator()().
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
As you see function takes "functor" by value(not by reference). It means that you has two objects:
The first of them it's Sum sum(0); (you created it explicitly).
The second is a copy of it.
for_each works with the copied object and the algorithm does not change your explicitly created object. But you can fix it by the following.
#include <iostream>
#include <algorithm>
#include <vector>
usingnamespace std;
class Sum
{
int t;
public:
Sum(int i):t(i){}
voidoperator()(int a)
{
t+=a;
cout <<"(a)" << a << "| t = " << t << endl; //trace the t value
}
int result() const
{
return t; //to return object value
}
};
int main()
{
vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
Sum sum(0);
Sum summa = for_each(vi.begin(),vi.end(),sum);
cout <<"Sum result: " <<summa.result() << endl;
}
And see jsmith's advice. If you need to get sum use accamulate.
jsmith, Denis, thank you very much. I had tried to find the solution by trace the process but I did not realise for_each takes copy rather than reference.