如何将对象放入 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 { ... };
^^^^^^^
我使用 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 { ... };
^^^^^^^