您可以从 C++ 中的转换函数使用的函数访问当前迭代器吗?
Can you access the current iterator from a function used by the transform function in 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};}
);
有没有办法在使用转换时从原始数组中引用前后值?
很明显,工具 std::transform
根本没有给你一个方法来做到这一点:它要么需要一个 unary 谓词来应用于一个元素的单个元素集合,或应用于两个集合的 对应元素 的 binary 谓词。
但重点是,从函数式编程的角度来看,您要做的根本不是转换。
你怎么能改为这样做呢?你可以压缩那个向量,我们称它为 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 | <a href="https://en.cppreference.com/w/cpp/ranges/drop_view" rel="nofollow noreferrer">drop(1)</a>
为您提供元素 {2,3,4,5,6}
和 v | drop(2)
对 {3,4,5,6}
的视图; zip_with
采用 n 元函数和 n 范围并组合 n 元组使用 n-ary 函数从 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}
你能否从 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};}
);
有没有办法在使用转换时从原始数组中引用前后值?
很明显,工具 std::transform
根本没有给你一个方法来做到这一点:它要么需要一个 unary 谓词来应用于一个元素的单个元素集合,或应用于两个集合的 对应元素 的 binary 谓词。
但重点是,从函数式编程的角度来看,您要做的根本不是转换。
你怎么能改为这样做呢?你可以压缩那个向量,我们称它为 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 | <a href="https://en.cppreference.com/w/cpp/ranges/drop_view" rel="nofollow noreferrer">drop(1)</a>
为您提供元素 {2,3,4,5,6}
和 v | drop(2)
对 {3,4,5,6}
的视图; zip_with
采用 n 元函数和 n 范围并组合 n 元组使用 n-ary 函数从 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}