为什么在Lambda移动时未调用移动构造函数

Why is the move constructor not called when moving in a lambda?

本文关键字:移动 调用 构造函数 Lambda 为什么      更新时间:2023-10-16

我正在尝试编译以下代码:

#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是可以的。为什么这不使用移动构造函数?

catch在此处的 operator()默认情况下是lambda代表的匿名类类型的CC_3。这意味着您无法从p2_1移动,因为Lambda的this是该功能中的const&。您需要做的是使用mutable关键字,例如

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

使函数非const的

又意味着您可以突变其成员。这使您可以移动p2_1而不是尝试复制它。