for_each 中的 C++ 仿函数意外行为

标签 c++ stl functor

考虑以下示例:

#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 保持不变?有人可以给我详细说明发生了什么吗?

最佳答案

那是因为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 中,使用 lambda 的 for_each:

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

关于for_each 中的 C++ 仿函数意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32131043/

相关文章:

c++ - 将自定义程序部署到托管服务

c++ - std::map 的插入提示是否有任何位置限制?

c++ - 在没有分配的情况下加入并重新拆分两个 std::list

c++ - '<' token 之前的预期初始化器

C++ STL pop_heap 不工作

c++ - 仿函数和模板

c++ - 无符号长整型

c++ - 如何测试引用是否为 NULL?

haskell - 处理(深度嵌套)仿函数的正确方法是什么?

haskell - 如何在 Haskell 中处理大量仿函数?