For example I have a vector
std::vector<int> source;
and a struct
struct Foo {
int x;
int y;
}
and I wish to do the following
Foo foo;
auto tr = source | boost::adaptors::transform([&](int i){return i+foo.x;};
However the above doesn't compile in the version of boost(1.55) and the compiler version(VS-2010) I am required to use. The problem is that when the lambda captures a variable by reference, the transform adaptor ends up trying to use the assign constructor which is illegal and fails to compile. However if nothing is captured then it all works.
My naive solution would be to wrap transform with another overload such that
Foo foo;
auto tr = source | boost::adaptors::transformed(foo, [](int i, Foo f){return i+f.x;};
This seems to be the pattern preferred by the std library. For example std::lower_bound uses this pattern.
but as soon as I try to think about how to do that I get stuck in template madness trying to wrap the original transform function. If somebody could show me how to generate the overload I require I am sure I could extrapolate that to the other overloads I need.
The alternative solution is instead of using lambdas is to use full functors for each function but this is ugly if I can at least use non capturing lambdas.
All the machinery of
boost::adaptors::transformed
funnels down toboost::iterator::transform_iterator
.transformed
is a type alias, sotransformed(fun)
is constructing an object, it isn't a function call to be overloaded.The simplest thing would be to copy
iterator/transform_iterator.hpp
andrange/adaptor/transformed.hpp
into abitransform_iterator.hpp
andbitransformed.hpp
with an extraParam p
(and renameUnaryFunctor
toBinaryFunctor
for clarity)