Using a functor on for_each

Why doesn't calling for_each on a functor update sum::total at the end?

 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}; std::for_each(arr, arr+6, s); cout << s.total << endl; // prints total = 0; } 
+7
source share
4 answers

for_each takes a functor by value - therefore, it is copied. You can, for example, use a functor that 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; } 
+9
source

for_each gets a copy of your functor by value. Even after that, he can freely copy it, but returns a copy.

OTOH, you are just trying to reinvent std::accumulate , which will make things easier:

 int total = std::accumulate(arr, arr+6, 0); cout << total << endl; 
+3
source

Because s that you pass to for_each is by value. for_each takes value 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 

Ideon Demo: http://ideone.com/s7OOn


Or you can simply write in std::cout :

 std::cout<<std::for_each(arr,arr+6,[&](int n)->int{sum += n;return sum;})(0); 

Launch: http://ideone.com/7Hyla

Please note that such a different syntax is suitable for learning how std::for_each , and that it returns, but I would not recommend this syntax in real code. std::for_each


In C ++, you can write a custom transform function in a functor since

 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; } 

This is a slightly different version of Erik's second solution: http://ideone.com/vKnmA

+3
source

This is because std :: for_each requires the functor to be passed by value. 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; } 
0
source

All Articles