复制捕获移动对象的 lambda
Copy lambda which captures moved object
为什么这个 code snippet 不能编译?
#include <functional>
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> uniq_ptr(new int{6});
auto foo_a = [&uniq_ptr]{std::cout << *uniq_ptr << std::endl;};
std::bind(foo_a)(); //works
foo_a(); //works
auto foo_b = [up = std::move(uniq_ptr)]()mutable{*up = 5; std::cout << *up << std::endl;};
foo_b(); //works;
#ifdef CHOOSE_1
auto foo_b1 = foo_b; //Surprised! I think `up` could be copied.But the compiler complains: Error: use of deleted function 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)'
#else
std::bind(foo_b); //Same error!
#endif
}
对于auto foo_b = [up = std::move(uniq_ptr)]()mutable{//...}
,我认为foo_b
可以被复制,因为up
是一个右值,它可以被移动构造函数复制。
[up = std::move(uniq_ptr)]
只是将 uniq_ptr
移动到 lambda 的成员变量。
std::bind
将在内部构建 foo_b
的副本。由于 foo_b
包含不可复制的 unique_ptr
,因此 foo_b
本身不可复制。
您应该将 foo_b
移动到 std::bind
:
std::bind(std::move(foo_b));
或将foo_b
移动到foo_b1
auto foo_b1 = std::move(foo_b);
为什么这个 code snippet 不能编译?
#include <functional>
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> uniq_ptr(new int{6});
auto foo_a = [&uniq_ptr]{std::cout << *uniq_ptr << std::endl;};
std::bind(foo_a)(); //works
foo_a(); //works
auto foo_b = [up = std::move(uniq_ptr)]()mutable{*up = 5; std::cout << *up << std::endl;};
foo_b(); //works;
#ifdef CHOOSE_1
auto foo_b1 = foo_b; //Surprised! I think `up` could be copied.But the compiler complains: Error: use of deleted function 'main()::<lambda()>::<lambda>(const main()::<lambda()>&)'
#else
std::bind(foo_b); //Same error!
#endif
}
对于auto foo_b = [up = std::move(uniq_ptr)]()mutable{//...}
,我认为foo_b
可以被复制,因为up
是一个右值,它可以被移动构造函数复制。
[up = std::move(uniq_ptr)]
只是将 uniq_ptr
移动到 lambda 的成员变量。
std::bind
将在内部构建 foo_b
的副本。由于 foo_b
包含不可复制的 unique_ptr
,因此 foo_b
本身不可复制。
您应该将 foo_b
移动到 std::bind
:
std::bind(std::move(foo_b));
或将foo_b
移动到foo_b1
auto foo_b1 = std::move(foo_b);