Как поместить объекты в `std :: tuple` и взять первый элемент с помощью операций только для перемещения? - PullRequest
0 голосов
/ 07 декабря 2018

Я использую лямбду, чтобы поместить объекты разных типов в кортеж и передать ее второй лямде, чтобы получить первый элемент.Идея состоит в том, чтобы использовать только операции перемещения, но следующий код все еще нуждается в копии, чтобы получить первые элементы из кортежа.

#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

Я не понимаю, где в цепочке происходит эта копия.

Итак, вопрос:
Возможно ли это сделать с помощью операций только для перемещения (и как)?

1 Ответ

0 голосов
/ 07 декабря 2018

Кортеж tp скопирован здесь:

return lmb(tp);
           ^^

сюда

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

Первый должен быть return lmb(std::move(tp));

Вам также нужно будет сделать лямбду mutable, поскольку по умолчанию захваты const.

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