Why does the for_each
call on functor doesn\'t update sum::total
at the end?
struct sum
{
sum():total(0){};
int total;
for_each
receives a copy of your functor by value. Even after that, it's free to copy it, but does return a copy.
OTOH, you're simply trying to re-invent std::accumulate
, which will do the job much more easily:
int total = std::accumulate(arr, arr+6, 0);
cout << total << endl;
Because the s
which you pass to the for_each
is by value. for_each
accepts it by value!
In C++0x, you can solve this problem with for_each
as,
int sum = 0;
std::for_each(arr, arr+6, [&](int n){ sum += n; });
std::cout << sum ;
Output:
15
Demo at ideone : http://ideone.com/s7OOn
Or you can simple write in the std::cout
itself:
std::cout<<std::for_each(arr,arr+6,[&](int n)->int{sum += n;return sum;})(0);
Run : http://ideone.com/7Hyla
Note such different syntax is okay for learning purpose, as to how std::for_each
works, and what it returns, but I would not recommend this syntax in real code. :-)
In C++, you can write user-defined conversion function in the functor as,
struct add
{
int total;
add():total(0){};
void operator()(int element) { total+=element; }
operator int() { return total ; }
};
int main()
{
int arr[] = {0, 1, 2, 3, 4, 5};
int sum = std::for_each(arr, arr+6, add());
std::cout << sum;
}
It's slightly different version from Erik second solution : http://ideone.com/vKnmA
This happens due to std::for_each requires the functor to be passed by value . A workaround for your solution:
struct sum
{
sum():total(0){};
int total;
sum(sum & temp)
{
total = temp.total;
}
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s); // result of for_each assigned back to s
cout << s.total << endl; // prints total = 0;
}
for_each
takes the functor by value - so it is copied. You can e.g. use a functor which is initialized with a pointer to an external int.
struct sum
{
sum(int * t):total(t){};
int * total;
void operator()(int element)
{
*total+=element;
}
};
int main()
{
int total = 0;
sum s(&total);
int arr[] = {0, 1, 2, 3, 4, 5};
std::for_each(arr, arr+6, s);
cout << total << endl; // prints total = 15;
}
Or you can use the return value from for_each
struct sum
{
sum():total(0){};
int total;
void operator()(int element)
{
total+=element;
}
};
int main()
{
sum s;
int arr[] = {0, 1, 2, 3, 4, 5};
s = std::for_each(arr, arr+6, s);
cout << s.total << endl; // prints total = 15;
}