首页 > 解决方案 > 如何创建具有用于捕获上下文的额外参数的 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,这很丑陋。

标签: c++boost-range

解决方案


boost::adaptors::transformed漏斗的所有机械都下降到boost::iterator::transform_iterator. transformed是类型别名,transformed(fun)构造对象也是如此,它不是要重载的函数调用。

最简单的方法是将iterator/transform_iterator.hppand复制range/adaptor/transformed.hpp到一个bitransform_iterator.hppandbitransformed.hppParam p(为了清楚起见,重命名UnaryFunctorBinaryFunctor


推荐阅读