std::function 的仅移动版本

2023-11-22

Because std::function是可复制的,该标准要求用于构造它的可调用对象也是可复制的:

n337 (20.8.11.2.1)

template<class F> function(F f);

要求:F应是可复制构造的。f对于参数类型应是可调用的 (20.8.11.2)ArgTypes和返回类型R。 A 的复制构造函数和析构函数不应抛出异常。

这意味着不可能形成一个std::function来自不可复制的绑定对象或捕获仅移动类型的 lambda,例如std::unique_ptr.

似乎可以为仅移动可调用对象实现这样的仅移动包装器。是否有一个标准库仅移动等效项std::function或者,这个问题有通用的解决方法吗?


不,没有仅移动版本std::function在C++中std图书馆。 (从 C++14 开始)

最快的代表是一个实现std::function就像上课的速度比大多数课程都快std::function在许多实施std库,并且应该很容易分叉成move and copy版本。

包裹你的move只将函数对象转化为shared_ptr<F>在有转发的班级中operator()是另一种方法。

这里有一个task sketch:

template<class Sig>
struct task;

namespace details {
  template<class Sig>
  struct task_iimpl;
  template<class R, class...Args>
  struct task_iimpl<R(Args...)> {
    virtual ~task_iimpl() {}
    virtual R invoke(Args&&...args) const = 0;
  };
  template<class F, class Sig>
  struct task_impl;
  template<class F, class R, class...Args>
  struct task_impl<F,R(Args...)>:
    task_iimpl<R(Args...)>
  {
    F f;
    template<class T>
    task_impl(T&& t):f(std::forward<T>(t)) {}
    virtual R invoke(Args&&...args) const override {
      return f( std::forward<Args>(args...) );
    }
  };
  template<class F, class...Args>
  struct task_impl<F,void(Args...)>:
    task_iimpl<void(Args...)>
  {
    F f;
    template<class T>
    task_impl(T&& t):f(std::forward<T>(t)) {}
    virtual void invoke(Args&&...args) const override {
      f( std::forward<Args>(args...) );
    }
  };
}
template<class R, class...Args>
struct task<R(Args...)> {
  virtual ~task_iimpl() {}
  R operator()(Args...args) const {
    return pImpl->invoke(std::forward<Args>(args...));
  }
  explicit operator bool()const{ return static_cast<bool>(pImpl); }
  task(task &&)=default;
  task& operator=(task &&)=default;
  task()=default;

  // and now for a mess of constructors
  // the rule is that a task can be constructed from anything
  // callable<R(Args...)>, destroyable, and can be constructed
  // from whatever is passed in.  The callable feature is tested for
  // in addition, if constructed from something convertible to `bool`,
  // then if that test fails we construct an empty task.  This makes us work
  // well with empty std::functions and function pointers and other tasks
  // that are call-compatible, but not exactly the same:
  struct from_func_t {};
  template<class F,
    class dF=std::decay_t<F>,
    class=std::enable_if_t<!std::is_same<dF, task>{}>,
    class FR=decltype(std::declval<F const&>()(std::declval<Args>()...)),
    std::enable_if_t<std::is_same<R, void>{} || std::is_convertible<FR, R>{} >*=0,
    std::enable_if_t<std::is_convertible<dF, bool>{}>*=0
  >
  task(F&& f):
    task(
      static_cast<bool>(f)?
      task( from_func_t{}, std::forward<F>(f) ):
      task()
    )
  {}
  template<class F,
    class dF=std::decay_t<F>,
    class=std::enable_if_t<!std::is_same<dF, task>{}>,
    class FR=decltype(std::declval<F const&>()(std::declval<Args>()...)),
    std::enable_if_t<std::is_same<R, void>{} || std::is_convertible<FR, R>{} >*=0,
    std::enable_if_t<!std::is_convertible<dF, bool>{}>*=0
  >
  task(F&& f):
    task( from_func_t{}, std::forward<F>(f) )
  {}

  task(std::nullptr_t):task() {}
  // overload resolution helper when signatures match exactly:
  task( R(*pf)(Args...) ):
    task( pf?task( from_func_t{}, pf ):task() )
  {}
private:
  template<class F,
    class dF=std::decay_t<F>
  >
  task(from_func_t, F&& f):
    pImpl( std::make_unique<details::task_impl<dF,R(Args...)>>(
      std::forward<F>(f)
    )
  {}

  std::unique_ptr<details::task_iimpl<R(Args...)> pImpl;
};

但它还没有经过测试或编译,我只是写了它。

更具工业强度的版本将包括一个小型缓冲区优化(SBO)来存储小型可调用对象(假设它们是可移动的;如果不可移动,则存储在堆上以允许移动),以及一个“如果你猜到了就获取指针”类型正确(如std::function).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::function 的仅移动版本 的相关文章

  • 部署 MVC4 项目时出错:找不到文件或程序集

    过去 我只需使用 Visual Studio 2012 发布到 AWS 菜单项即可部署我的 MVC4 网站 到 AWS Elastic Beanstalk 现在 程序可以在本地编译并运行 但无法部署 从消息来看 它似乎正在寻找不在当前部署的
  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的

随机推荐

  • OpenSSL 静态库太大,有什么替代方法或方法可以减小其大小?

    我已经使用了 OpenSSL 1 0 的预构建静态库 但它使我的二进制文件太大 在发布模式下将其大小增加了约 800Kb 我不需要 OpenSSL 的大部分功能 例如 BIO 我使用自己的套接字 因此在代码中我只使用几个 SSL XXXXX
  • 如何防止ggplot2中的轴相交

    我正在使用 ggplot2 制作一些对数转换数据的线图 这些数据都有很大的值 在 10 6 和 10 8 之间 由于轴不是从零开始 我不想让它们在 原点 相交 以下是轴当前的样子 我更喜欢从基础图形中获得的东西 但我另外使用geom rib
  • 3D 中两个矩形之间的交集

    为了获得 3D 中两个矩形之间的交线 我将它们转换为平面 然后使用法线的叉积获得交线 然后尝试获得与矩形的每个线段的线交点 问题是这条线平行于三段 并且只与 NAN NAN NAN 中的一条相交 这是完全错误的 你能告诉我我的代码有什么问题
  • TabLayout 的选项卡未显示

    我有一个主要活动 它托管一个片段 该片段又托管一个 TabLayout 带有 ViewPager 显示选项卡栏 但不显示选项卡本身 这是我在主要活动中用于显示主机片段的代码 Fragment fragment new BMITabsFrag
  • 应用程序更新时的警报管理器[重复]

    这个问题在这里已经有答案了 我正在开发一个使用的应用程序AlarmManager对于某些进程 我想问一下我是否在 Playstore 上更新我的应用程序 更新而不是新安装 注册的警报会被取消吗 还将值SharedPreference重置 A
  • 如何从 python 中的 RFC 2822 邮件标头中提取多个电子邮件地址?

    蟒蛇的email模块非常适合解析标头 但是 那To header可以有多个接收者 并且可能有多个To 标头 那么如何拆分每个电子邮件地址呢 我不能用逗号分隔 因为逗号可以被引用 有没有办法做到这一点 演示代码 msg To email pr
  • 在内容脚本中使用 chrome.tabs 或其他 chrome API 时,“无法读取未定义的属性”

    chrome tabs尽管我在权限块中设置了选项卡 但仍返回未定义 permissions tabs http https content scripts matches http https js js myScript js all f
  • custom_require.rb:36:in `require': 没有要加载的文件 -- myapp(LoadError)

    我收到上述错误 我所做的就是安装 rvm 并从 Mac 获得的默认 ruby 更新到 ruby 1 9 2 我的所有宝石都出现在宝石列表中 但我需要在某处指定路径吗 cheers glenno 检查您是否安装了 gemgem list如果没
  • 防止Bootstrap崩溃崩溃

    我有一个 Bootstrap 折叠 标题内有一个按钮 按钮上有clickEvent 我想防止单击按钮时发生崩溃事件 有人有提示吗 这在这里没有帮助 buttonId live click function e e preventDefaul
  • NumPy 中是否提供十进制“dtypes”?

    是十进制数据类型对象 dtypes 在 NumPy 中可用吗 gt gt gt import decimal numpy gt gt gt d decimal Decimal 1 1 gt gt gt s 123 123 23 2323 2
  • 如何在 Flutter 中使用 SQFlite 进行数据库插入

    如何使用 SQFlite 插件将数据插入 Flutter 数据库 有很多解决问题的问题 但我找不到一个可以添加规范答案的问题 我的回答如下 添加依赖项 Open pubspec yaml并在依赖项部分添加以下行 sqflite 1 0 0
  • 检测html5移动设备中的晃动

    我目前正在 html5 中构建一个 Web 应用程序 它需要能够检测用户何时摇动手机以及摇动手机的速度 我一直在浏览 但似乎找不到任何如何实现这一点的示例 我知道html5有一个加速度计可以检测手机的方向 但是它如何检测用户摇动手机的速度呢
  • CSS:如果背景图像大于窗口,则缩小背景图像,否则保持 100%

    我想在我的网站正文中部署一个背景图像 该图像会随着窗口分辨率的变化而缩小 但不会放大到超出其原始尺寸 1920x1080 这样 分辨率较小的用户仍然可以看到整个图像 但分辨率更高的用户就不会看到丑陋的放大背景 它看起来不像背景图像支持像 m
  • 使用 mongoose api 和 nodejs 搜索数据库?

    我正在使用nodejs和mongoose构建一个api 我正在尝试执行搜索功能 但它似乎无法查询任何内容 即代码 app get search function req res return Questions find text nood
  • 限制列表(Of T)的大小 - VB.NET

    我试图限制通用列表的大小 以便在它包含一定数量的值后 它不会再添加任何值 我尝试使用 List 对象的 Capacity 属性来执行此操作 但这似乎不起作用 Dim slotDates As New List Of Date slotDat
  • 字符串小数点后 3 位

    实施例1 Dim myStr As String 38 我希望我的结果是38 000 实施例2 myStr 6 4 我希望我的结果是6 400 实现这一目标的最佳方法是什么 我想格式化一个string变量至少有小数点后三位 places U
  • 使用 PostgreSQL 根据选择查询中的字段删除重复行?

    考虑到表mdl files包含以下字段 id contenthash timecreated filesize 该表存储附件文件 我们认为具有相同内容哈希的所有行都是重复行 我只想保留最旧的行 或者如果日期相等则保留第一行 我怎样才能做到这
  • DebuggerStepThrough 被忽略

    我最近注意到 Visual Studio 2010 调试器不断跳转到这个标有 DebuggerStepThrough 属性 调用堆栈看起来像这样 Page OnLoad 调用一个方法是泛型的子类在标记为的类中 DebuggerStepThr
  • 如何使用 pdf.js 从 pdf 文档获取元数据

    有没有办法使用 pdf js 从 pdf 文档中获取元数据 例如作者或标题 在这个例子中 http mozilla github io pdf js web viewer html file compressed tracemonkey p
  • std::function 的仅移动版本

    Because std function是可复制的 该标准要求用于构造它的可调用对象也是可复制的 n337 20 8 11 2 1 template