如何从移动捕获lambda表达式创建一个std :: function?

 hgsfaerqw_504 发布于 2022-12-26 13:08

我正在尝试创建std::function一个移动捕获lambda表达式.请注意,我可以创建一个移动捕获lambda表达式而不会出现问题; 只有当我尝试将其包装成一个std::function我得到错误时.

例如:

auto pi = std::make_unique(0);

// no problems here!
auto foo = [q = std::move(pi)] {
    *q = 5;
    std::cout << *q << std::endl;
};

// All of the attempts below yield:
// "Call to implicitly-deleted copy constructor of ' bar = foo;
std::function bar{foo};
std::function bar{std::move(foo)};
std::function bar = std::move(foo);
std::function bar{std::forward>(foo)};
std::function bar = std::forward>(foo);

我会解释为什么我要写这样的东西.我写了一个UI库,类似于jQuery的或JavaFX的,允许用户通过传递给处理鼠标/键盘事件std::functions到方法有相似的名字on_mouse_down(),on_mouse_drag(),push_undo_action(),等.

显然,std::function我想要传入的理想情况下应该使用移动捕获lambda表达式,否则我需要求助于我在C++ 11作为标准时使用的丑陋的"release/acquire-in-lambda"习语:

std::function baz = [q = pi.release()] {
    std::unique_ptr p{q};
    *p = 5;
    std::cout << *q << std::endl;
};

请注意,调用baz两次将是上述代码中的错误.但是,在我的代码中,这个闭包保证只被调用一次.

顺便说一句,在我的真实代码中,我并没有传递一个std::unique_ptr,而是一些更有趣的东西.

最后,我正在使用Xcode6-Beta4,它使用以下版本的clang:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

Robert Allan.. 31

template function(F f);

template function(allocator_arg_t, const A& a, F f);

要求: F应该是CopyConstructible.f应该是Callable参数类型ArgTypes和返回类型R.A的拷贝构造函数和析构函数不应抛出异常.

§20.9.11.2.1[func.wrap.func.con]

请注意,这operator =是根据此构造函数定义的swap,因此适用相同的限制:

template function& operator=(F&& f);

功效: function(std::forward(f)).swap(*this);

§20.9.11.2.1[func.wrap.func.con]

因此,要回答你的问题:是的,这是可以构建一个std::function从一招捕获拉姆达(因为这仅指定拉姆达如何捕捉),但它是不是可以构建一个std::function唯才是举型(如MOVE-捕获lambda,移动捕获不可复制的东西.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有