C++中使用transform时能否访问当前迭代器获取相邻元素值
C++ transform函数访问相邻元素实现方案
核心结论:直接使用默认单序列值传递的transform写法无法访问相邻元素,必须通过捕获上下文实现。
你原有写法的问题在于传入std::transform的lambda仅接收当前元素的数值作为参数,没有携带原容器的上下文信息,因此无法直接获取前后相邻元素的值。你可以通过lambda捕获上下文的方式实现需求,也可以选择可读性更高的普通循环实现。
实现方案
- 方案1:lambda捕获原容器与遍历索引(兼容C++11及以上版本)
#include <vector> #include <algorithm> int main() { std::vector<int> originalPoints = {1,2,4,3,5,6}; // 提前为目标容器分配足够空间 std::vector<int> alteredValues(originalPoints.size() - 2); // 初始下标指向原容器第二个元素(下标为1) int cur_idx = 1; std::transform(originalPoints.begin() + 1, originalPoints.end() - 1, alteredValues.begin(), [&](int current_val) { int res = originalPoints[cur_idx - 1] + current_val + originalPoints[cur_idx + 1]; cur_idx++; return res; }); // 最终alteredValues结果为[7,9,12,14] return 0; }
注意:该方案仅适用于支持随机访问的容器(如std::vector、std::array),非随机访问容器通过下标访问元素开销较高。
- 方案2:C++20下标范围遍历(无手动索引维护,更安全)
#include <vector> #include <algorithm> #include <ranges> int main() { std::vector<int> originalPoints = {1,2,4,3,5,6}; std::vector<int> alteredValues(originalPoints.size() - 2); // 直接遍历有效下标范围 std::ranges::transform(std::views::iota(1, (int)originalPoints.size() - 1), alteredValues.begin(), [&](int idx) { return originalPoints[idx-1] + originalPoints[idx] + originalPoints[idx+1]; }); return 0; }
- 更简洁的替代方案:普通for循环
如果不需要强制使用std::transform,直接写普通for循环可读性更高,也避免了捕获变量可能带来的错误:
std::vector<int> originalPoints = {1,2,4,3,5,6}; std::vector<int> alteredValues; alteredValues.reserve(originalPoints.size() - 2); for (int i = 1; i < originalPoints.size() - 1; ++i) { alteredValues.push_back(originalPoints[i-1] + originalPoints[i] + originalPoints[i+1]); }
内容的提问来源于stack exchange,提问作者blake
相关产品推荐
相关产品推荐

