2015-08-21 2 views
4

Рассмотрим следующий пример:C++ функтор неожиданное поведение в for_each

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

Я ожидал, что сумма будет 25, но он печатает 0. Почему f остались без изменений? Может ли кто-нибудь дать мне подробный отчет о том, что происходит?

ответ

5

Это потому, что std::for_each принимает свой функтор на значение, а не по ссылке. Он работает внутри на копии f, и тот, который вы передаете, остается неизменным. Это делает возвращения функтора обратно к вам, чтобы вы могли просто перезаписать ваш:

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

Или, торчащий с C++ 03, которые accum взять ссылку:

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

Хотя, возможно, вы может быть просто хочу std::accumulate:

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

Или, в C++ 11, for_each с лямбда:

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

Спасибо. Очень полезно. – HyunSangTae

Смежные вопросы