C++中的 for_each
函数是for循环的一种替代方案。for_each
位于算法库中,调用的时候需要包含algorithm头文件。
for_each
的原型为:
template<class InputIt, class UnaryFunction> UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
前两个参数为起止迭代器,第三个参数是一个一元函数。C++11标准已经实现了闭包,第三个参数可以使用闭包替代,无需额外再定义函数实体。
下面是 for_each
的一个简单应用:
#include <vector> #include <algorithm> #include <iostream> int main() { std::vector<int> nums{3, 4, 2, 9, 15, 267}; std::cout < < "before: "; for (auto n : nums) { std::cout << n << " "; } std::cout << '\n'; std::for_each(nums.begin(), nums.end(), [](int &n){ n++; }); std::cout << "after: "; for (auto n : nums) { std::cout << n << " "; } return 0; }
上述代码将输出:
before: 3 4 2 9 15 267 after: 4 5 3 10 16 268
可以看到for_each的使用还是非常方便的。需要说明的是第三个参数是函数,其接收值应当为 *InputIt
类型。上述案例中vector的元素是 int
类型,所以闭包的参数类型也应该是 int
类型。并且我们使用的是引用调用。
再来看一个复杂的例子:
std::map<std::string , CFoo*> _map; // some codes for_each ( _map.begin(), _map.end(), [](std::pair<std::string , CFoo*> value) { value.second->run(); });
上述示例中,操作对象为map类型,匿名函数的接受对应改成了相应的 pair
类型。上述代码编译和运行都没有问题,结果也正确。但是如果有一个函数,需要接受引用参数,可能会引发问题:
for_each ( _map.begin(), _map.end(), [](std::pair<std::string , CFoo*>& value) { value.second->setDefault(); });
setDefault
函数将_map对象里的值变成默认值,我们希望此操作是引用调用,对输入参数有影响。直接看上面的代码,应该没有问题,遗憾的是上述代码编译不能通过。编译器报了一堆错误,其中有个重要的就是说转换失败。
问题出在了对 map
的key的改变上,第三个函数接受的pair对象应当是保持key不变的,当时上面的叙述没有体现这一点。所以正确的做法是:
for_each ( _map.begin(), _map.end(), [](std::pair<const std::string, CFoo*>& value) { value.second->setDefault(); });
需要把key声明为const类型,这样才能编译通过。
解决了一个坑,以后还需要多学习c++的东西。
原文链接:https://www.qiquanji.com/post/4775.html
本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。
微信扫码关注
更新实时通知