• 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的示例代码:

    1. #include
    2. #include
    3. void foo(int a, int b)
    4. {
    5. std::cout << "a + b = " << a + b << std::endl;
    6. }
    7. class Bar
    8. {
    9. public:
    10. void operator()(int a, int b)
    11. {
    12. std::cout << "a - b = " << a - b << std::endl;
    13. }
    14. };
    15. int main()
    16. {
    17. int a = 10, b = 5;
    18. std::invoke(foo, a, b); // 调用普通函数
    19. Bar bar;
    20. std::invoke(bar, a, b); // 调用函数对象
    21. std::invoke(&Bar::operator(), bar, a, b); // 调用成员函数
    22. std::function<void(int, int)> f = foo;
    23. std::invoke(f, a, b); // 调用std::function对象
    24. return 0;
    25. }

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

    function与invoke的区别

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

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

    1. #include
    2. #include
    3. void foo(int a, int b)
    4. {
    5. std::cout << "foo(" << a << ", " << b << ")" << std::endl;
    6. }
    7. int main()
    8. {
    9. std::function<void(int, int)> f = foo;
    10. f(1, 2);
    11. }

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

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

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

    1. #include
    2. #include
    3. void foo(int a, int b)
    4. {
    5. std::cout << "foo(" << a << ", " << b << ")" << std::endl;
    6. }
    7. class Bar {
    8. public:
    9. void bar(int a, int b) const
    10. {
    11. std::cout << "Bar::bar(" << a << ", " << b << ")" << std::endl;
    12. }
    13. };
    14. int main()
    15. {
    16. std::invoke(foo, 1, 2);
    17. Bar b;
    18. std::invoke(&Bar::bar, &b, 1, 2);
    19. }

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

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

  • 相关阅读:
    vue项目路由使用history模式,nginx配置,刷新页面显示404
    不抖机灵!让工程师来告诉你做芯片是如何烧钱的!
    一个小型公司怎么落地微服务
    计算机算法分析与设计(11)---贪心算法(活动安排问题和背包问题)
    谷歌浏览器插件开发 --- 实现华为状态码弹出
    万宾科技智能井盖,实现对井盖的监测
    (四)旋转物体检测数据roLabelImg转DOTA格式
    【Unity入门计划】CreatorKitFPS:第一人称射击3D小游戏
    前端工程化小记
    flutter开发实战-StreamBuilder使用介绍及实例
  • 原文地址:https://blog.csdn.net/huanxiajioabu/article/details/134072016