【问题标题】:Cannot std::move from lambda capture to function call inside lambda, why? [duplicate]无法将 std::move 从 lambda 捕获移动到 lambda 内部的函数调用,为什么? [复制]
【发布时间】:2018-07-31 08:40:38
【问题描述】:

在下面的代码中

#include <memory>
#include <thread>
#include <utility>

void f1(std::unique_ptr<int>&& uptr) {}

void f(std::unique_ptr<int>&& uptr)
{
    auto thread = std::thread([uptr{ std::move(uptr) }]() {
        f1(std::move(uptr));
    });
}

int main()
{
    return 0;
}

无法编译 lambda 内对 std::move 的调用:

[x86-64 gcc 8.1 #1] error: binding reference of type'std::unique_ptr<int>&&'
to 'std::remove_reference<const> std::unique_ptr<int>&>::type'
{aka 'const std::unique_ptr<int>'} discards qualifiers

现场演示:https://godbolt.org/g/9dQhEX

为什么会出现此错误,我该如何解决? const来自哪里?

【问题讨论】:

    标签: c++ c++14


    【解决方案1】:

    您需要将 lamdba 设为 mutable,因为默认情况下闭包变量是 const-qualified。

    auto thread = std::thread([uptr{ std::move(uptr) }]() mutable {
                                                        //^^^^^^
    
         f1(std::move(uptr)); /* Works, no constness-violation.*/
     });
    

    【讨论】:

    • “默认情况下闭包变量是 const 限定的” - 我不知道,谢谢!
    • 少数几个默认使用const-ness 的地方之一。我希望更多。
    • 救命稻草。我花了很长时间试图解决这个问题。
    【解决方案2】:

    您应该使 lambda 状态可变:

    auto thread = std::thread([uptr{ std::move(uptr) }]() mutable
    

    【讨论】:

      猜你喜欢
      • 2018-06-08
      • 2019-03-05
      • 2022-01-27
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 2020-08-17
      • 1970-01-01
      相关资源
      最近更新 更多