c++ - 如何创建具有用于捕获上下文的额外参数的 boost::range::transform 版本
问题描述
例如我有一个向量
std::vector<int> source;
和一个结构
struct Foo {
int x;
int y;
}
我希望做以下事情
Foo foo;
auto tr = source | boost::adaptors::transform([&](int i){return i+foo.x;};
但是,以上内容不能在我需要使用的 boost(1.55) 版本和编译器版本(VS-2010) 中编译。问题是当 lambda 通过引用捕获变量时,转换适配器最终会尝试使用非法的分配构造函数并且无法编译。但是,如果没有捕获任何内容,则一切正常。
我天真的解决方案是用另一个重载包装变换,这样
Foo foo;
auto tr = source | boost::adaptors::transformed(foo, [](int i, Foo f){return i+f.x;};
这似乎是 std 库首选的模式。例如std::lower_bound使用这种模式。
但是一旦我尝试考虑如何做到这一点,我就陷入了试图包装原始变换函数的模板疯狂中。如果有人可以向我展示如何生成我需要的重载,我相信我可以将其推断为我需要的其他重载。
另一种解决方案不是使用 lambda,而是为每个函数使用完整的函子,但如果我至少可以使用非捕获 lambda,这很丑陋。
解决方案
boost::adaptors::transformed
漏斗的所有机械都下降到boost::iterator::transform_iterator
. transformed
是类型别名,transformed(fun)
构造对象也是如此,它不是要重载的函数调用。
最简单的方法是将iterator/transform_iterator.hpp
and复制range/adaptor/transformed.hpp
到一个bitransform_iterator.hpp
andbitransformed.hpp
中Param p
(为了清楚起见,重命名UnaryFunctor
为BinaryFunctor
)
推荐阅读
- indicator - 如何解决此行字符不匹配错误?
- c - 是否可以在不违反严格别名的情况下将字符数组用作内存池?
- c++ - 可以创建一个函数来一般设置传入的结构成员吗?
- json - 如何访问地图列表中的数据?
- python - 在 Python 中评分 R 模型
- scala - 如何在 Spark 读取时捕获 spark.read FileNotFoundException?
- ruby-on-rails - 重命名 Rails 6.1 应用程序后的 Webpack / Yarn 错误
- python - 在基于函数的视图中将多个值解析为 user_passes_test
- python - 从 mpl 平行坐标图中删除图例?
- angular - Angular 的 Kendo UI 不显示任何数据