简体   繁体   English

为什么我不能在C ++ 14中移动lambda中的std :: unique_ptr?

[英]Why can't I move the std::unique_ptr inside lambda in C++14?

I want to pass a raw pointer inside lambda, but I don't want it to be leaked, if the lambda isn't invoked. 我想在lambda中传递一个原始指针,但我不希望它被泄露,如果没有调用lambda。 It looks like this: 它看起来像这样:

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.
  });
}

I get an error in Clang 3.7.0: 我在Clang 3.7.0中收到错误:

error: binding of reference to type 'unique_ptr<[2 * ...]>' to a value of type 'unique_ptr<[2 * ...]>' drops qualifiers 错误:将类型'unique_ptr <[2 * ...]>'的引用绑定到类型'unique_ptr <[2 * ...]>'的值会丢弃限定符

But I don't see any qualifiers at the first place, especially dropped. 但是我没有看到任何限定词,尤其是掉线。

Also, I found similar report on the mailing list, but without answer. 另外,我在邮件列表上找到了类似的报告 ,但没有回答。


How should I modify my code, so it gets compiled and works as expected by semantics? 我应该如何修改我的代码,以便编译并按语义按预期工作?

You need to make the inner lambda mutable : 你需要使内部lambda mutable

[this](Pointer* list) {
  thread_pool.Push([this, list = std::unique_ptr<int>(list) ]() mutable {
                                                               ^^^^^^^^^
    Clean(std::move(list));
  });
};

operator() on lambdas is const by default, so you cannot modify its members in that call. 默认情况下,lambdas上的operator()const ,因此您无法在该调用中修改其成员。 As such, the internal list behaves as if it were a const std::unique_ptr<int> . 因此,内部list行为就像是const std::unique_ptr<int> When you do the move cast, it gets converted to a const std::unique_ptr<int>&& . 当你进行move转换时,它会转换为const std::unique_ptr<int>&& That's why you're getting the compile error about dropping qualifiers: you're trying to convert a const rvalue reference to a non-const rvalue reference. 这就是为什么你得到关于删除限定符的编译错误:你试图将const rvalue引用转换为非const rvalue引用。 The error may not be as helpful as it could be, but it all boils down to: you can't move a const unique_ptr . 该错误可能没有那么有用,但它归结为:你不能move const unique_ptr

mutable fixes that - operator() is no longer const , so that issue no longer applies. mutable修复 - operator()不再是const ,因此该问题不再适用。

Note: if your Clean() took a unique_ptr<int> instead of a unique_ptr<int>&& , which makes more sense (as it's a more explicit, deterministic sink), then the error would have been a lot more obvious: 注意:如果你的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
    ^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 捕获并移动c ++ 14 lambda表达式中的unique_ptr - Capture and move a unique_ptr in a c++14 lambda expression 如何从 C++14 中的广义 lambda 捕获返回包含 std::unique_ptr 的 std::function? - How to return a std::function that contains a std::unique_ptr from a generalized lambda capture in C++14? c ++ 14 unique_ptr并使用删除的函数&#39;std :: unique-ptr&#39;使用unique_ptr错误 - c++14 unique_ptr and make unique_ptr error use of deleted function 'std::unique-ptr' 为什么list <unique_ptr>中的unique_ptr的std :: move()没有真正移动它? - Why doesn't std::move() of unique_ptr from list<unique_ptr> really move it? 为什么我可以在不使用 std::move 的情况下将 std::unique_ptr 复制到另一个? - Why can I copy std::unique_ptr into another one without using std::move? std :: move或std :: forward,参数为std :: unique_ptr <T> &amp;&amp; - std::move or std::forward with parameter std::unique_ptr<T>&& 将std :: unique_ptr移动到std :: vector内的新位置 - Move std::unique_ptr to new position inside std::vector 无法初始化std :: unique_ptr - Can't initialize std::unique_ptr 为什么我不能使用std :: unique_ptr作为“模板” <class> 阶级“论证? - Why can't I use std::unique_ptr as a “template<class> class” argument? 移动std :: vector <std::unique_ptr<T> &gt;到std :: vector <std::shared_ptr<T> &gt; - Move std::vector<std::unique_ptr<T>> to std::vector<std::shared_ptr<T>>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM