移动lambda:一旦您捕获了仅移动类型,就如何使用lambda? [英] Moving a lambda: once you've move-captured a move-only type, how can the lambda be used?

查看:98
本文介绍了移动lambda:一旦您捕获了仅移动类型,就如何使用lambda?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此答案说明了如何在C ++ 14中的lambda中移动捕获变量.

This answer explains how to move-capture a variable within a lambda in C++14.

但是一旦您在Lambda中移动捕获了不可复制的对象(例如std::unique_ptr),就无法复制Lambda本身.

But once you've move-captured an un-copyable object (such as a std::unique_ptr) within a lambda, you cannot copy the lambda itself.

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

This would be fine if you could move the lambda, but I get a compile error when trying to do so:

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++出现以下错误(我尝试仅复制相关行):

This produces the following error with g++ (I've attempted to copy only the relevant line):

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

...我认为这意味着我尝试移动lambda的尝试失败了.

...implying, I think, that my attempt to move the lambda has failed.

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

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

I tried explicitly moveing the lambda (even though it's a temporary value), but that did not help.

编辑:以下答案充分解决了上述代码产生的编译错误.对于另一种方法,只需将唯一指针的目标值release放入std::shared_ptr中,就可以将其复制 . (我不是将其写为答案,因为这会假定这是一个XY问题,但是必须理解为什么unique_ptr不能用于转换为std::function的lambda中的根本原因. )

The answers below adequately address the compile errors produced by the above code. For an alternate approach, simply release the unique pointer's target value into a std::shared_ptr, which can be copied. (I'm not writing this as an answer, because that would assume that this is an XY problem, but the underlying reason why unique_ptr can't be used in a lambda that gets converted to a std::function is important to understand.)

很有趣的是,据我所知,我只是意识到auto_ptr实际上会在这里做正确的事情(!).它的行为本质上与unique_ptr相似,但允许复制构造代替move-construction.

EDIT 2: Hilariously enough, I just realized auto_ptr would actually do the right thing here (!), as far as I can tell. It acts essentially like unique_ptr, but allows copy-construction in place of move-construction.

推荐答案

您可以移动 lambda ,很好.但这不是您的问题所在,您正在尝试使用不可复制的lambda实例化std::function.还有:

You can move the lambda, that's fine. That's not what your problem is though, you're trying to instantiate a std::function with a noncopyable lambda. And the:

template< class F > 
function( F f );

function

构造函数执行:

constructor of function does:

5)使用f副本初始化目标.

5) Initializes the target with a copy of f.

这是因为 std::function :

满足CopyConstructible和CopyAssignable的要求.

satisfies the requirements of CopyConstructible and CopyAssignable.

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

Since function has to be copyable, everything you put into it must also be copyable. And a move-only lambda does not meet that requirement.

这篇关于移动lambda:一旦您捕获了仅移动类型,就如何使用lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆