如何用C++标准算法替代循环实现两个vector间的对象方法调用?
用C++标准算法实现成对容器元素的操作
嘿,你的需求完全可以用C标准库的工具来实现,不同C版本有不同的优雅方案,我给你梳理一下:
C++20及以上:最优解(用范围库)
C++20引入的**范围库(Ranges)**提供了std::views::zip,可以直接把两个容器的元素一一配对,配合std::ranges::for_each就能完美替代你的索引循环,代码非常简洁:
#include <ranges> #include <algorithm> // 假设a和b已初始化且大小相等 std::ranges::for_each(std::views::zip(a, b), [](auto&& [elem_a, elem_b]) { elem_a.Method(elem_b); });
这里用了C++17的结构化绑定,直接把配对的元素拆成elem_a和elem_b,可读性拉满。如果你的编译器还不完全支持结构化绑定,也可以用std::get来访问配对里的元素:
std::ranges::for_each(std::views::zip(a, b), [](auto&& pair) { std::get<0>(pair).Method(std::get<1>(pair)); });
C++20之前:兼容方案
如果还在用C11/C17,没有范围库的话,有两种靠谱的方式:
方式1:用std::transform
虽然std::transform主要设计用来做元素转换,但我们可以利用它支持双输入迭代器的特性来实现需求。这里我们把结果写回第一个容器(因为我们只是修改a的元素,不需要新容器):
#include <algorithm> std::transform(a.begin(), a.end(), b.begin(), a.begin(), [](A& elem_a, const B& elem_b) -> A& { elem_a.Method(elem_b); return elem_a; // 返回值只是满足transform的接口要求 });
方式2:自定义辅助函数
如果觉得std::transform的用法有点“歪门邪道”,你可以自己写一个极简的辅助函数,风格和标准算法一致:
#include <algorithm> template <typename Iter1, typename Iter2, typename Func> void for_each_pair(Iter1 first1, Iter1 last1, Iter2 first2, Func func) { while (first1 != last1) { func(*first1++, *first2++); } } // 使用时直接调用: for_each_pair(a.begin(), a.end(), b.begin(), [](A& elem_a, const B& elem_b) { elem_a.Method(elem_b); });
这个函数非常轻量,兼容所有C++版本,而且逻辑清晰,完全符合你想要的类似std::apply的调用风格。
另外要提一句:你提到的std::apply其实是用来调用tuple中的元素作为函数参数的,和遍历容器配对元素的需求不匹配,所以不能用它来实现这个功能哦。
内容的提问来源于stack exchange,提问作者Gophys
相关产品推荐
相关产品推荐

