c++ - move lambda : once you've move-captured a move-only type, 如何使用 lambda?

标签 c++ lambda move c++14

This answer解释了如何在 C++14 中 move 捕获 lambda 中的变量。

但是,一旦您在 lambda 中 move 捕获了一个不可复制的对象(例如 std::unique_ptr),您就无法复制 lambda 本身。

如果您可以 move lambda,这会很好,但尝试这样做时会出现编译错误:

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

g++ 会产生以下错误(我试图只复制相关行):

error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’

...我认为,这意味着我 move lambda 的尝试失败了。

clang++ 给出了类似的错误。

我尝试显式move lambda(即使它是一个临时值),但这并没有帮助。

编辑: 下面的答案充分解决了上述代码产生的编译错误。对于另一种方法,只需将唯一指针的目标值releasestd::shared_ptr 中,可以 复制。 (我没有写这个作为答案,因为那会假设这是一个 XY 问题,但是 unique_ptr 不能在转换为 的 lambda 中使用的根本原因>std::function 理解起来很重要。)

编辑 2: 好笑的是,据我所知,我刚刚意识到 auto_ptr 实际上会在这里做正确的事情(!)。它的行为本质上类似于 unique_ptr,但允许复制构造代替 move 构造。

最佳答案

你可以 move lambda,没关系。不过,这不是您的问题,您正在尝试使用不可复制的 lambda 实例化 std::function 。还有:

template< class F > 
function( F f );

function 的构造函数确实:

5) Initializes the target with a copy of f.

这是因为 std::function :

satisfies the requirements of CopyConstructible and CopyAssignable.

由于 function 必须是可复制的,因此您放入其中的所有内容也必须是可复制的。而只能 move 的 lambda 不满足该要求。

关于c++ - move lambda : once you've move-captured a move-only type, 如何使用 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32486623/

相关文章:

Python Tkinter canvas.tag_bind()

c++ - QApplication::processEvents 在 Windows 中不工作

python - 用缺失键的默认值替换 pandas 列中的值

c# - Lambda 和类型推断

C# 窗体 move 停止事件

C++ Move构造函数无法编译

c++ - 我的 xml 标签正则表达式不起作用

c++ - 为什么 stringstream >> 在失败时更改目标值?

c++ - 从串口解码二进制数据

c# - 如何 'not' Entity Framework 的 lambda 表达式