首页 > 解决方案 > 为什么将结构函数传递给 for_each 循环不会改变结构属性

问题描述

我是 C++ 新手,我正在学习 C++20。我正在尝试一个结构函数,即将一个函数包装在一个结构中,而我们可以在这个结构中声明本地属性。

问题是当我将此结构函数传递给for_each函数时,它不起作用。

#include<algorithm>
#include<iostream>
#include<string>
#include<vector>

using namespace std;

struct accumulateAmount{
    int total_amount;
    accumulateAmount() { total_amount = 100 ;} //constructor
    void operator()(int num){
        total_amount += num;
    }
};


int main(){ 
    vector<int> nums{1,2,3,4,5};
    accumulateAmount acctor;
    for_each(nums.begin(), nums.end(), acctor);
    cout << acctor.total_amount << endl;
    return 0;
    
}

输出是100。它没有实现累加器功能。

而如果我将循环从for_each普通的for循环更改为如下:

for (int i = 0; i < nums.size(); i++){
      acctor(nums[i]);
}
 

有用。

所以我想知道是不是因为'for_each'包含并行计算,因此对于向量中的每个int,我们对它们使用独立的函数?

标签: c++

解决方案


std::for_each按值取函数。所以你的函数被复制了,并std::for_each调用了copy。这就是为什么你acctor没有得到修改。

您可以通过使用强制通过引用传递std::ref

for_each(nums.begin(), nums.end(), std::ref(acctor));

或者,也许更惯用的是,您可以捕获的返回值std::for_each

auto const result = for_each(nums.begin(), nums.end(), accumulateAmount());
std::cout << result.total_amount << "\n";

这段代码的好处是您甚至不需要为 引入名称acctor:您可以传递一个临时值并即时创建函数对象。这很好,因为这意味着您可以制作所有本地对象const

也就是说,std::for_each具有可变函数对象绝对不是惯用的 C++。找到合适的算法并不总是显而易见的,但总是值得的。在这种情况下,您将使用std::reduce

auto const result = std::reduce(nums.begin(), nums.end(), 100);
std::cout << result << "\n";

推荐阅读