C++中invoke与function的区别

news2024/11/18 21:24:14

C++ invoke

invoke是C++17标准引入的一个函数模板,用来调用可调用对象(Callable Object,如函数指针、函数对象、成员函数指针等)并返回结果。

invoke提供了统一的调用语法,无论可调用对象的类型是什么,都可以使用同一种方式进行调用。

详见:https://en.cppreference.com/w/cpp/utility/functional/invoke

图片

在C++17之前,调用不同类型的可调用对象需要使用不同的语法,比如直接调用函数、使用类对象的运算符重载操作符()来调用函数对象、使用成员函数指针来调用类成员函数等等。这些调用方式虽然能用,但是不够灵活,而invoke解决了这种不一致的问题。

invoke函数的实现原理是通过使用SFINAE(Substitution Failure Is Not An Error)技术来判断可调用对象的类型,并根据类型调用对应的调用方式。因此,无论可调用对象的类型是什么,都可以使用invoke函数来调用,而不需要使用不同的语法。

它的实现原理可以看https://en.cppreference.com/w/cpp/utility/functional/invoke

下面是invoke的示例代码:

#include <iostream>
#include <functional>

void foo(int a, int b)
{
    std::cout << "a + b = " << a + b << std::endl;
}

class Bar
{
public:
    void operator()(int a, int b)
{
        std::cout << "a - b = " << a - b << std::endl;
    }
};

int main()
{
    int a = 10, b = 5;
    std::invoke(foo, a, b); // 调用普通函数
    Bar bar;
    std::invoke(bar, a, b); // 调用函数对象
    std::invoke(&Bar::operator(), bar, a, b); // 调用成员函数
    std::function<void(int, int)> f = foo;
    std::invoke(f, a, b); // 调用std::function对象
    return 0;
}

总结:std::invoke 提供了一种通用的函数调用语法,可以方便地调用各种可调用对象。

function与invoke的区别

std::function和std::invoke是两个不同的东西,功能也不同。std::function是一个函数对象的封装器,可以用来封装任意类型的可调用对象,比如函数指针、lambda表达式等,而 std::invoke 则是一个函数模板,用于在统一的接口下调用可调用对象。

比如,我们可以使用std::function来存储一个函数指针:

#include <functional>
#include <iostream>

void foo(int a, int b)
{
    std::cout << "foo(" << a << ", " << b << ")" << std::endl;
}

int main()
{
    std::function<void(int, int)> f = foo;
    f(1, 2);
}

上述代码中,我们将函数指针foo封装成了一个std::function对象f,然后通过调用f(1, 2)来调用函数foo

std::invoke的作用是提供一种通用的函数调用语法,可以用统一的方式来调用各种可调用对象,而不必关心它们具体是什么类型。

比如,可以使用std::invoke来调用一个东西,无论这个东西是函数指针、函数对象还是成员函数指针:

#include <functional>
#include <iostream>

void foo(int a, int b)
{
    std::cout << "foo(" << a << ", " << b << ")" << std::endl;
}

class Bar {
public:
    void bar(int a, int b) const
{
        std::cout << "Bar::bar(" << a << ", " << b << ")" << std::endl;
    }
};

int main()
{
    std::invoke(foo, 1, 2);

    Bar b;
    std::invoke(&Bar::bar, &b, 1, 2);
}

上面代码,使用std::invoke分别调用了函数foo和类Bar的成员函数bar,并传递了相应的参数。

总结,std::functionstd::invoke的使用场景是不同的。std::function 适用于需要存储可调用对象的场景,而std::invoke则适用于统一调用各种不同类型的可调用对象的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1139569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

工业自动化产品抗干扰笔记

工业自动化产品抗干扰笔记 名词解释&#xff1a; 耦合矢量控制寄生振荡热噪点闪变噪点尖峰噪点反电势集肤效应交流电阻感抗容抗寄生电容共模与差模电场和磁场漏电流浪涌电压电流传输与电压传输各种地线解析 一、干扰来源&#xff1a; 任何一个电磁干扰现象都具有电磁干扰源…

大促期间的窜货低价怎么处理

产品窜货往往会伴随低价&#xff0c;所以监测窜货就是要先监测低价&#xff0c;当然有些产品卖价不低价也窜货&#xff0c;但这些正价或者高价卖的链接对渠道影响并不太大&#xff0c;所以治理低价窜货更重要。 力维网络专业为品牌提供窜货治理&#xff0c;低价监测的需求&…

NodeRed Modbus学习一(配置Modsim32)

新手小白 第一次使用这个玩意 会弹出一个小白框&#xff0c;不用管它。 新建File 下面两张图可以看出值在变化 通过下图可以看出还没有链接 创建连接 好了

在项目管理中,项目经理要控制这三个重要因素:进度、成本、质量

项目管理贯穿项目的整个生命周期&#xff0c;对项目的整个过程进行管理&#xff0c;对项目进行计划、组织、指导和控制的手段。 在项目的生命周期内&#xff0c;进行资源的配置和协调&#xff0c;做出科学决策&#xff0c;从而使项目执行的全过程处于最佳的运行状态&#xff…

04.Animation

参考JusterZhu视频和文档&#xff0c;ppt文档基本全抄 基本没看懂&#xff0c;过几天有时间了研究下 一、Animation 1.什么是Animation&#xff1f; 动画是快速循环播放一系列图像&#xff08;其中每个图像与下一个图像略微不同&#xff09;给人造成的一种幻觉。再回到WPF开发…

微信公众号分销商城源码系统+多商户入驻+互动直播+整点秒杀 带部署教程

今天罗峰来给大家分享一款微信公众号分销商城源码系统。微信公众号的普及以及电商行业的兴起&#xff0c;一种新型的商业模式——微信公众号分销商城应运而生。这种模式通过微信平台&#xff0c;将线上与线下的商业活动完美结合&#xff0c;为企业提供了更广阔的销售渠道。以下…

如何在群晖NAS中搭建WebDav服务,并实现公网访问

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 1. 在群晖套件中心安装WebDav Server套件1.1 安装完成后&#xff0c;启动webdav服务&#xff0c;并勾选HTTP复选…

stable-diffusion-webui环境部署

stable-diffusion-webui环境部署 1. 环境创建2. 安装依赖库3.下载底模4.运行代码5. 报错信息报错1报错2 1. 环境创建 创建虚拟环境 conda create -n env_stable python3.10.0进入虚拟环境 conda activate env_stableclone源码 git clone https://github.com/AUTOMATIC1111/stab…

设备管理软件管理系统

从设备检查到设备保养&#xff0c;再到设备维护&#xff0c;全方位视角掌握设备状态的管理软件。让企业员工可以随时随地的查看设备的各种信息&#xff1a;巡检信息、保养计划、备件更换提醒、维修保养资料等。 1、一物一码&#xff0c;建立设备电子档案“身份证” 精准管控每一…

31 select max/min/avg/sum/count/group_concat 的实现

前言 avg, sum, max, min, count 的相关使用 这里来调试一下 具体的情况, 以及看一下 索引对于相关操作的影响 测试数据表如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(12) DEFAULT NULL,field2 varchar(16) DEFAULT NULL,PRI…

漏洞复现--企望制造ERP系统 RCE

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

ADB加密实例

ADB加密实例 1. adb shell加密访问2 adb文件传输命令加密访问 通常我们的MIFI USB端口仅枚举rndis和mass端口&#xff0c;为了便于开发人员、工厂维护人员调试和运营商认证&#xff0c;会预留出可通过SCSI指令切口支持ADB端口&#xff0c;该机制可能会被作为切入点破解侵入系统…

OA管理系统源码

OA管理系统源码 功能介绍 1、个人办公 a、内部邮件&#xff08;写邮件&#xff0c;收邮件&#xff0c;草稿箱&#xff0c;已删除&#xff0c;已发送&#xff09; b、Internet邮件&#xff08;写邮件&#xff0c;收邮件&#xff0c;草稿箱&#xff0c;已发送&#xff0c;已删…

Java实现人脸识别和指纹认证

我们在开发中经常会有人脸识别的需求&#xff0c;今天就实现一个简单的人脸识别&#xff0c;调用的第三方SDK服务 0.先去注册服务 登录网址 虹软视觉开放平台—以免费人脸识别技术为核心的人脸识别算法开放平台 点击进行注册 进入之后新增我的服务 成功之后点击首页人脸识别…

《SpringBoot项目实战》第一篇—接口参数的一些弯弯绕绕

系列文章导航 第一篇—接口参数的一些弯弯绕绕 第二篇—接口用户上下文的设计与实现 第三篇—留下用户调用接口的痕迹 第四篇—接口的权限控制 第五篇—接口发生异常如何统一处理 本文参考项目源码地址&#xff1a;summo-springboot-interface-demo 前言 大家好&#xff01;…

MessageQueue 深入理解Android卷2 学习笔记

MessageQueue类封装了与消息队列有关的操作&#xff0c;一个以消息驱动的系统中&#xff0c;最重要部分就是消息队列和消息处理循环。 MessageQueue的核心代码在native层&#xff0c;可以处理java和native的事件 1.1MessageQueue创建 构造方法&#xff0c;调用nativeInit fra…

外网访问|SD-WAN跨境网络专线助力企业摆脱网络困境

在如今国际市场的大趋势下&#xff0c;跨境访问和沟通对于外贸企业来说至关重要&#xff0c;国际市场的竞争越来越激烈&#xff0c;外贸企业需要与全球各地的合作伙伴、客户和供应商保持紧密的跨境访问和沟通。而在解决跨境网络困境方面&#xff0c;MPLS、VPN和SD-WAN是常见的选…

CVE漏洞复现-CVE-2023-38831 WinRAR代码执行漏洞

CVE-2023-38831 WinRAR代码执行漏洞 WinRAR介绍 WinRAR 是一款功能强大的压缩包管理器&#xff0c;它是档案工具RAR在 Windows环境下的图形界面。 该软件可用于备份数据&#xff0c;缩减电子邮件附件的大小&#xff0c;解压缩从 Internet 上下载的RAR、ZIP及其它类型文件&…

装了固态硬盘Win10开机很慢的解决方法

在Win10电脑中&#xff0c;用户反映自己装了固态硬盘后&#xff0c;电脑开机变得很慢&#xff0c;想知道解决此问题的方法。接下来小编给大家详细介绍关于解决装了固态硬盘Win10电脑开机很慢的问题&#xff0c;解决后Win10电脑开机速度就能变得更快。 装了固态硬盘Win10开机很慢…

【速看】如何通过合理的封装,让你的自动化脚本更上一层楼!

1. 前言 上一篇推文利用一个在图片范围内实现随机坐标点击的例子&#xff0c;去教会大家如何将自己想要的效果实现出来&#xff0c;受到大家的热情反响&#xff0c;在我们官方讨论群中&#xff0c;还有大佬对我们的示例代码进行优化改进&#xff0c;做了很多合理的函数封装&…