首页 > 解决方案 > 您可以从 c++ 中的转换函数使用的函数访问当前迭代器吗?

问题描述

您可以从 c++ 中的转换函数使用的函数访问当前迭代器,以便可以引用之前和之后的值吗?我想使用 transform 函数遍历一个向量,对依赖于当前值之前和之后值的向量执行操作。

例如,假设我有一个值为 [1,2,4,3,5,6] 的向量,我想从第二个值开始,并迭代直到倒数第二个值。在这些元素中的每一个上,我想创建一个新值,该值等于该值的总和,以及原始值中它旁边的值。结束向量看起来像 [7,9,12,14]。

auto originalsBeginIterator = originalPoints.begin();
auto originalsEndIterator = originalPoints.end();
std::advance(originalsBeginIterator, 1);
std::advance(originalsEndIterator,-1);
std::transform(originalsBeginIterator,originalsEndIterator,alteredValues.begin(),
[](int x) x = { return {previous value} + x + {next value};} 
);

使用变换时,有什么方法可以引用原始数组中的前一个和后一个值?

标签: c++functional-programming

解决方案


显然,该工具std::transform根本没有为您提供执行此操作的方法:它要么将一谓词应用于一个集合的单个元素,要么将二元谓词应用于两个集合的相应元素

但关键是,从函数式编程的角度来看,您尝试做的根本不是转换。

你怎么能这样做呢?你可以压缩那个向量,我们称之为v,同一个向量被剥夺了它的第一个元素,同一个向量被剥夺了它的第二个元素;然后,您将对每对的 3 个元素求和。

Range-v3 为您提供了一种非常简洁的方法:

#include <iostream>
#include <range/v3/view/drop.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/zip_with.hpp>
#include <vector>

using namespace ranges::views;
int main()
{
    // input
    std::vector<int> v{1,2,3,4,5,6};

    // to sum 3 ints
    auto constexpr plus = [](int x, int y, int z){ return x + y + z; };

    // one-liner
    auto w = zip_with(plus, v, v | drop(1), v | drop(2));

    // output
    std::cout << w << std::endl;
}

v | drop(1)给你一个关于元素的观点{2,3,4,5,6},以及v | drop(2)关于{3,4,5,6}; zip_with采用n元函数和n范围,并使用 n 元函数组合来自n范围的相应元素的n元组。所以在我们的例子中,它会是这样的:

v                         = {1, 2, 3, 4, 5, 6}
                             +  +  +  +
v1 = v | drop(1)          = {2, 3, 4, 5, 6}
                             +  +  +  +
v2 = v | drop(2)          = {3, 4, 5, 6}
zip_with(plus, v, v1, v2) = {6, 9,12,15} 

推荐阅读