为什么在 lambda 中移动时不调用移动构造函数?
Why is the move constructor not called when moving in a lambda?
我正在尝试编译以下代码:
#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
没问题。为什么这不使用移动构造函数?
这里的问题是 lambda 表示的匿名 class 类型的 operator()
默认是 const
。这意味着您不能从 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
而不是试图复制它。
我正在尝试编译以下代码:
#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
没问题。为什么这不使用移动构造函数?
这里的问题是 lambda 表示的匿名 class 类型的 operator()
默认是 const
。这意味着您不能从 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
而不是试图复制它。