Подтвердить что ты не робот

Почему конструктор перемещения не вызывается при перемещении в лямбда?

Я пытаюсь скомпилировать следующий код:

#include <utility>

struct C2 {
        C2() = default;
        C2(C2 const&) = delete;
        C2(C2&&) = default;
};

int main() {
        C2 p2;
        ([p2_1{ std::move(p2) }]() {
                auto p2_2 = std::move(p2_1); // <---
        })();
        return 0;
}

Однако это не компилируется и дает ошибку, что назначение p2_2 вызывает удаленную функцию, а именно конструктор копирования. Обратите внимание, что переход на p2_1 прекрасен. Почему это не использует конструктор перемещения?

4b9b3361

Ответ 1

Ловушка здесь заключается в том, что operator() типа анонимного класса, по умолчанию, имеет значение lambda const. Это означает, что вы не можете перейти от p2_1, так как this лямбда const& в функции. Что вам нужно сделать, это использовать ключевое слово mutable, например

int main() {
        C2 p2;
        ([p2_1{ std::move(p2) }]() mutable {
                auto p2_2 = std::move(p2_1); // <---
        })();
        return 0;
}

Что делает функцию non const, которая, в свою очередь, означает, что вы можете мутировать ее членов. Это позволяет вам перемещать p2_1 вместо того, чтобы копировать его.