首页 > 编程语言 >C++ invoke与function的区别

C++ invoke与function的区别

时间:2023-10-27 09:55:59浏览次数:33  
标签:function std 调用 invoke int C++ foo

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则适用于统一调用各种不同类型的可调用对象的场景。

标签:function,std,调用,invoke,int,C++,foo
From: https://www.cnblogs.com/blizzard8204/p/17791098.html

相关文章

  • C++运算符
    C++运算符运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C++内置了丰富的运算符,并提供了以下类型的运算符:算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符算术运算符下表显示了C++支持的所有算术运算符。假设变量A=10;B=20,则:运算符描......
  • murmurhash64B c# 实现 c++ 实现
    c#实现:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespacegjh.utility{publicclassMurmurHash64B{publicstaticulongMakeHashValue(byte[]key,uintseed=0xee6b27eb){......
  • C++ 与 QML 之间进行数据交互的几种方法
    一、属性绑定这是最简单的方式,可以在QML中直接绑定C++对象的属性。通过在C++对象中使用Q_PROPERTY宏定义属性,然后在QML中使用绑定语法将属性与QML元素关联起来。person.h#include<QObject>classPerson:publicQObject{Q_OBJECT/*使用Q_PROPERTY定义交......
  • c++中的继承(下)
    首先我们先回忆一下,在派生类(子类)中默认的成员函数做了什么事情?我们现在可以这么认为对于普通类来说呢?只需要看待两个部分的成员:内置类型和自定义类型。而对于派生类而言序言看待三个部分的成员:内置类型,自定义类型以及父类类型构造和析构拷贝构造普通类对于内置类型一般不处理,自定类......
  • kernel function: the difference beween cdev_add and device_create
     Touseacharacterdriver,firstyoushouldregisteritwiththesystem.Thenyoushouldexposeittotheuserspace. 1.cdev_initandcdev_addfunctionsperformthecharacterdeviceregistration.cdev_addaddsthecharacterdevicetothesystem.When......
  • C++修饰符类型
    C++允许在char、int和double数据类型前放置修饰符。修饰符用于改变基本类型的含义,所以它更能满足各种情境的需求。当前有以下几种数据类型修饰符:signedunsignedlongshort修饰符signed、unsigned、long和short可应用于整型,signed和unsigned可应用于字符型,long可应用于双精度......
  • 【每日例题】 蓝桥杯 c++ 考勤刷卡
    考勤刷卡题目小蓝负责一个公司的考勤系统,他每天都需要根据员工刷卡的情况来确定每个员工是否到岗。当员工刷卡时,会在后台留下一条记录,包括刷卡的时间和员工编号,只要在—天中员工刷过—次卡,就认为他到岗了。现在小蓝导出了—天中所有员工的刷卡记录,请将所有到岗员工的员工......
  • 现代C++语言核心特性解析 谢丙堃​ 2021年pdf电子版
    现代C++语言核心特性解析2021年pdf电子版作者: 谢丙堃出版年: 2021-10ISBN: 9787115564177连接提取码:ckop自从C++11发布,就没有系统学习C++的书,也很久没有看国内作者出的C++书籍了。市面上对于现代C++的书很少,这是一本讲述现代C++11~C++20的书。意外,写得不错,容易理解,难得是除了......
  • C++中vector容器详解
    参考链接:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html一、什么是vector?向量(Vector)是一个封装了动态大小数组的顺序容器(SequenceContainer)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。二......
  • 引用C++程序,在DOS命令行打印彩色玫瑰花
    python代码:fromctypesimport*importpygameimportrandomimportstringimporttimeif__name__=='__main__':withopen('log.txt','rb')asf:lines=f.readlines()count=0forlineinlines:......