This answer giải thích cách di chuyển chụp một biến trong một lambda trong C++ 14.Di chuyển một lambda: một khi bạn đã di chuyển một loại di chuyển chỉ, làm thế nào có thể lambda được sử dụng?
Nhưng khi bạn đã di chuyển một đối tượng không thể sao chép được (chẳng hạn như std::unique_ptr
) trong một lambda, bạn không thể sao chép chính lambda.
Đây sẽ là tốt nếu bạn có thể di chuyển lambda, nhưng tôi nhận được một lỗi biên dịch khi cố gắng làm như vậy:
using namespace std;
class HasCallback
{
public:
void setCallback(std::function<void(void)>&& f)
{
callback = move(f);
}
std::function<void(void)> callback;
};
int main()
{
auto uniq = make_unique<std::string>("Blah blah blah");
HasCallback hc;
hc.setCallback(
[uniq = move(uniq)](void)
{
std::cout << *uniq << std::endl;
});
hc.callback();
}
này tạo ra các lỗi sau với g++
(Tôi đã cố gắng để sao chép chỉ dòng thích hợp):
error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’
... ngụ ý, tôi nghĩ rằng nỗ lực di chuyển lambda của tôi không thành công.
clang++
đưa ra lỗi tương tự.
Tôi đã thử rõ ràng move
nhập lambda (mặc dù đó là giá trị tạm thời), nhưng điều đó không giúp ích gì.
EDIT: Câu trả lời dưới đây giải quyết đầy đủ các lỗi biên dịch được tạo bởi mã trên. Đối với phương pháp thay thế, chỉ cần release
giá trị mục tiêu của con trỏ duy nhất vào một số std::shared_ptr
, trong đó có thể được sao chép. (Tôi không viết câu trả lời này, bởi vì điều đó sẽ cho rằng đây là vấn đề XY, nhưng lý do cơ bản tại sao unique_ptr
không thể được sử dụng trong lambda được chuyển đổi thành std::function
là điều quan trọng cần hiểu.)
EDIT 2: Hài hước đủ, tôi vừa nhận ra auto_ptr
thực sự sẽ làm điều đúng ở đây (!), Theo như tôi có thể nói. Nó hoạt động cơ bản như unique_ptr
, nhưng cho phép sao chép-xây dựng thay cho di chuyển-xây dựng.
Tôi nghĩ setCallback sẽ nhận được thông số theo giá trị chứ không phải là tài liệu tham khảo rvalue, tôi sai? – Slava
@Slava Đó là những gì tôi đã có ban đầu, nhưng nó đã cho cùng một lỗi. Tôi nghĩ lấy tham chiếu rvalue sẽ cho phép (/ force) lambda được di chuyển xây dựng, nhưng điều đó dường như không đúng. –