C++中带有lambdas的简单自定义迭代器
Simple customized iterator with lambdas in C++
假设我有一个容器,它包含int
,一个在包含Point
的容器上工作的函数,并且有一个函数,给定一些int
会给我它所代表的相应的Point
(假设我已经在某个大的std::vector<Point>
中索引了场景中的所有点)。如何创建一个简单(高效)的包装器来使用我的第一个容器而不复制其内容?
我想键入的代码是这样的:
template<typename InputIterator>
double compute_area(InputIterator first, InputIterator beyond) {
// Do stuff
}
template<typename InputIterator, typename OutputIterator>
void convex_hull(InputIterator first, InputIterator beyond, OutputIterator result) {
// Do stuff
}
struct Scene {
std::vector<Point> vertices;
foo(const std::vector<int> &polygon) {
// Create a simple wraper with limited amount of mumbo-jumbo
auto functor = [](int i) -> Point& { return vertices[polygon[i]]; });
MagicIterator polyBegin(0, functor);
MagicIterator polyEnd(polygon.size(), functor);
// NOTE: I want them to act as random access iterator
// And then use it directly
double a = compute_area(polyBegin, polyEnd);
// Bonus: create custom inserter similar to std::back_inserter
std::vector<int> result;
convex_hull(polyBegin, polyEnd, MagicInserter(result));
}
};
所以,正如你所看到的,我正在寻找一些通用的东西。我也想过使用lambdas,但我对如何保持它的简单性和用户友好性有点困惑。
我建议Boost的Transform Iterator。下面是一个用法示例:
#include <boost/iterator/transform_iterator.hpp>
#include <vector>
#include <cassert>
#include <functional>
struct Point { int x, y; };
template<typename It>
void compute(It begin, It end)
{
while (begin != end) {
begin->x = 42;
begin->y = 42;
++begin;
}
}
int main()
{
std::vector<Point> vertices(5);
std::vector<int> polygon { 2, 3, 4 };
std::function<Point&(int)> functor = [&](int i) -> Point& { return vertices[i]; };
auto polyBegin = boost::make_transform_iterator(polygon.begin(), functor);
auto polyEnd = boost::make_transform_iterator(polygon.end(), functor);
compute(polyBegin, polyEnd);
assert(vertices[2].y == 42);
}
我没有完全理解关于自定义back_inserter
的部分。如果存储在result
向量中的类型与functor返回的类型相同,则标准库中的类型即可。否则,您也可以将其封装在transform_iterator
中。
注意,函子存储在std::function
中。Boost依赖于函数来定义typedef result_type
,而lambdas没有。
我看到了两种方法。要么从boost::iterator_facade
开始,然后编写"函数迭代器"类型。
或者,使用boost::counting_iterator
迭代器或编写自己的迭代器(它们很容易),然后使用boost::transform_iterator
将Index
迭代器映射到Point
迭代器。
以上所有内容也可以直接编写。我会把它写成一个随机访问迭代器:它需要一些typedef
s、++
、--
、+=
、-=
、-
、+
s、比较以及*
和->
才能正确定义。它有点像样板,上面的boost
库只是让它成为一个无点样板(通过将样板本身包含在内)。
我已经为自己编写了一个版本,它将函数类型作为参数,然后将函数与索引一起存储。它使用索引推进/比较等,并使用函数类型取消引用。通过使函数类型为std::function<blah()>
,我得到了它的类型擦除版本,通过使它成为lambda参数的decltype
,或函子的类型,我得到一个更有效的版本。
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 如何正确实现和访问运算符的各种自定义枚举器
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 自定义先决条件对移动分配运算符有效吗
- 自定义层 API (TensorRT 2.1) 上的简单示例?
- 使用自定义简单 Mapi DLL,无需安装 Outlook
- 在自定义 C/C++ 程序中获取 PPP0 接口 Tx/Rx 字节的最简单方法是什么?
- 用C++编写的 MetaTrader 自定义指标的简单示例
- 如何将我的自定义模块与 Omnet++INET 的简单模块相结合
- c++ 中带有简单构造函数的向量和自定义类的问题
- 用于块内存的简单自定义分配器
- C++中带有lambdas的简单自定义迭代器
- 创建自定义简单Mapi DLL,执行时失败
- 带有自定义类的范围循环(矢量的简单版本<string>,使用分配器)
- 如何简单地循环自定义比例
- 简单的自定义互斥失败