C++ invoke与function的区别解析

 更新时间:2023年10月27日 09:57:43   作者:冰山奇迹  
invoke函数的实现原理是通过使用SFINAE(Substitution Failure Is Not An Error)技术来判断可调用对象的类型,并根据类型调用对应的调用方式,这篇文章主要介绍了C++ invoke与function的区别,需要的朋友可以参考下

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

到此这篇关于C++ invoke与function的区别的文章就介绍到这了,更多相关C++ invoke与function的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现并行计算的两种方式

    C++实现并行计算的两种方式

    本文介绍了使用C++实现并行计算的两种方式,包括OpenMP和MPI,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • 用VScode编写C++大型项目的方法步骤

    用VScode编写C++大型项目的方法步骤

    本文主要介绍了用VScode编写C++大型项目的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C语言实现绘制南丁格尔玫瑰图的示例代码

    C语言实现绘制南丁格尔玫瑰图的示例代码

    玫瑰图中有一种不等半径的统计图称为南丁格尔玫瑰图,网上很热门,是一很有艺术感的漂亮的统计图,下面我们就来看看如何使用C语言绘制它吧
    2024-03-03
  • 筛选法的C++实现

    筛选法的C++实现

    筛选法又称筛法,是求不超过自然数N(N>1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子
    2013-10-10
  • C++浅析数据在内存中如何存储

    C++浅析数据在内存中如何存储

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-08-08
  • C语言中字符串和数字的相互转换实现代码

    C语言中字符串和数字的相互转换实现代码

    以下是对C语言中字符串和数字的相互转换实现代码进行了分析介绍,需要的朋友可以参考下
    2013-07-07
  • C语言的编程之美之内存函数

    C语言的编程之美之内存函数

    这篇文章主要介绍了C语言全部内存操作函数的实现详细讲解,作者用图文代码实例讲解的很清晰,有感兴趣的同学可以研究下
    2021-09-09
  • C++实现简单BP神经网络

    C++实现简单BP神经网络

    这篇文章主要为大家详细介绍了C++实现简单BP神经网络,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • C++普通函数指针与成员函数指针实例解析

    C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下
    2014-08-08
  • C++ TinyXML解析案例详解

    C++ TinyXML解析案例详解

    这篇文章主要介绍了C++ TinyXML解析案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08

最新评论