如何将对象放入 std::tuple 并使用仅移动操作获取第一项?

How to put objects in `std::tuple` and take the first item with move-only operations?

我使用 lambda 将不同类型的对象放在一个元组中,并将其传递给第二个 lamda 以获取第一项。 这个想法是只使用移动操作,但下面的代码仍然需要一个副本来从元组中获取第一个项目。

#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));
}

这会产生以下输出:

MOVE
MOVE

MOVE
COPY
MOVE

我不明白这个副本发生在链中的什么地方。

所以问题是:
是否可以通过仅移动操作(以及如何)来做到这一点?

元组 tp 从此处复制:

return lmb(tp);
           ^^

到这里

[](auto tp) { ... }
        ^^

第一个需要return lmb(std::move(tp));

您还需要制作 lambda mutable,因为默认情况下捕获是 const

[tp = std::make_tuple(std::move(args)...)](auto lmb) mutable { ... };
                                                     ^^^^^^^