为什么我不能在 C++14 中移动 lambda 中的 std::unique_ptr?
Why can't I move the std::unique_ptr inside lambda in C++14?
我想在 lambda 中传递一个原始指针,但我不希望它在没有调用 lambda 的情况下被泄露。它看起来像这样:
void Clean(std::unique_ptr<int>&& list);
void f(int* list) {
thread_pool.Push([list = std::unique_ptr<int>(list) ] {
Clean(std::move(list)); // <-- here is an error.
});
}
我在 Clang 3.7.0 中遇到错误:
error: binding of reference to type 'unique_ptr<[2 * ...]>' to a value of type 'unique_ptr<[2 * ...]>' drops qualifiers
但是我一开始没有看到任何预选赛,尤其是掉线。
此外,我在邮件列表中发现了类似的 report,但没有得到答复。
我应该如何修改我的代码,使其按语义预期进行编译和工作?
您需要制作内部 lambda mutable
:
[this](Pointer* list) {
thread_pool.Push([this, list = std::unique_ptr<int>(list) ]() mutable {
^^^^^^^^^
Clean(std::move(list));
});
};
lambdas 上的 operator()
默认为 const
,因此您无法在该调用中修改其成员。因此,内部 list
的行为就好像它是 const std::unique_ptr<int>
一样。当您执行 move
转换时,它会转换为 const std::unique_ptr<int>&&
。这就是为什么您会收到有关删除限定符的编译错误的原因:您正在尝试将 const 右值引用转换为非 const 右值引用。该错误可能没有它应有的帮助,但这一切都归结为:你不能 move
a const unique_ptr
.
mutable
修复了 - operator()
不再是 const
,因此该问题不再适用。
注意:如果您的 Clean()
使用 unique_ptr<int>
而不是 unique_ptr<int>&&
,这更有意义(因为它是一个更明确、确定性的接收器),那么错误将是更明显了:
error: call to deleted constructor of `std::unique_ptr<int>`
note: 'unique_ptr' has been explicitly marked deleted here
unique_ptr(const unique_ptr&) = delete
^
我想在 lambda 中传递一个原始指针,但我不希望它在没有调用 lambda 的情况下被泄露。它看起来像这样:
void Clean(std::unique_ptr<int>&& list);
void f(int* list) {
thread_pool.Push([list = std::unique_ptr<int>(list) ] {
Clean(std::move(list)); // <-- here is an error.
});
}
我在 Clang 3.7.0 中遇到错误:
error: binding of reference to type 'unique_ptr<[2 * ...]>' to a value of type 'unique_ptr<[2 * ...]>' drops qualifiers
但是我一开始没有看到任何预选赛,尤其是掉线。
此外,我在邮件列表中发现了类似的 report,但没有得到答复。
我应该如何修改我的代码,使其按语义预期进行编译和工作?
您需要制作内部 lambda mutable
:
[this](Pointer* list) {
thread_pool.Push([this, list = std::unique_ptr<int>(list) ]() mutable {
^^^^^^^^^
Clean(std::move(list));
});
};
lambdas 上的 operator()
默认为 const
,因此您无法在该调用中修改其成员。因此,内部 list
的行为就好像它是 const std::unique_ptr<int>
一样。当您执行 move
转换时,它会转换为 const std::unique_ptr<int>&&
。这就是为什么您会收到有关删除限定符的编译错误的原因:您正在尝试将 const 右值引用转换为非 const 右值引用。该错误可能没有它应有的帮助,但这一切都归结为:你不能 move
a const unique_ptr
.
mutable
修复了 - operator()
不再是 const
,因此该问题不再适用。
注意:如果您的 Clean()
使用 unique_ptr<int>
而不是 unique_ptr<int>&&
,这更有意义(因为它是一个更明确、确定性的接收器),那么错误将是更明显了:
error: call to deleted constructor of `std::unique_ptr<int>`
note: 'unique_ptr' has been explicitly marked deleted here
unique_ptr(const unique_ptr&) = delete
^