如何创建一个版本的 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_iteratortransformed是类型别名,因此transformed(fun)构造对象,则不是要重载的函数调用。

最简单的方法是将iterator/transform_iterator.hpprange/adaptor/transformed.hpp复制到一个bitransform_iterator.hpp中,并使用额外的Param pbitransformed.hpp(并为清楚起见,UnaryFunctor重命名为BinaryFunctor(

相关内容

  • 没有找到相关文章

最新更新