I use a lambda to put objects of different types in a tuple and pass it to a second lamda to get the first item. The idea is to only use move-only operations, but the following code still needs a copy to get the first items from the tuple.
#include <iostream>
#include <tuple>
struct foo {
foo()=default;
foo(const foo &) { std::cout << "COPY\n"; }
foo(foo &&) { std::cout << "MOVE\n"; }
};
int main()
{
auto lst = [](auto ...args) {
return [tp = std::make_tuple(std::move(args)...)](auto lmb) { return lmb(tp); };
};
auto head = [](auto lmb) {
return lmb([](auto tp) { return std::move(std::get<0>(tp)); });
};
foo f ;
auto lmb = lst(std::move(f),1,2);
std::cout << std::endl;
auto r = head(std::move(lmb));
}
This produces the following output:
MOVE
MOVE
MOVE
COPY
MOVE
I don't understand where in the chain this copy takes place.
So the question is:
Is it possible to do this with move-only operations (and how) ?
The tuple, tp
, is copied from here:
return lmb(tp);
^^
to here
[](auto tp) { ... }
^^
The first one needs to be return lmb(std::move(tp));
You'll also need to make the lambda mutable
since captures are const
by default.
[tp = std::make_tuple(std::move(args)...)](auto lmb) mutable { ... };
^^^^^^^