在for_each上使用仿函数

时间:2011-03-12 22:37:18

标签: c++ stl functor

为什么for_each调用仿函数最后不会更新sum::total

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

4 个答案:

答案 0 :(得分:12)

for_each按值获取仿函数 - 因此会被复制。你可以,例如使用一个用外部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;
}

或者您可以使用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;
}

答案 1 :(得分:3)

for_each按价值收到您的仿函数副本。即使在那之后,它也可以自由复制,但确实会复制一份。

OTOH,你只是想重新发明std::accumulate,这将更容易地完成工作:

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

答案 2 :(得分:3)

因为您传递给s的{​​{1}}是值。 for_each按价值接受它!

在C ++ 0x中,您可以使用for_each as,

解决此问题
for_each

输出:

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

在ideone演示:http://ideone.com/s7OOn


或者你可以简单地写一下15 本身:

std::cout

运行:http://ideone.com/7Hyla

注意这种不同的语法可以用于学习目的,关于std::cout<<std::for_each(arr,arr+6,[&](int n)->int{sum += n;return sum;})(0); 如何工作以及它返回的内容,但我在实际代码中推荐这种语法。 : - )


在C ++中,您可以在仿函数中编写用户定义的转换函数,

std::for_each

与Erik第二解决方案略有不同:http://ideone.com/vKnmA

答案 3 :(得分:0)

这是因为std :: for_each需要按值传递仿函数。 解决方案的解决方法:

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