RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 848131
Accepted
Rivand
Rivand
Asked:2020-06-29 14:39:18 +0000 UTC2020-06-29 14:39:18 +0000 UTC 2020-06-29 14:39:18 +0000 UTC

为什么需要 std::invoke ?

  • 772

我现在看到在第 17 个标准中有一个新的模板功能std::invoke。我很高兴,因为。我认为它与 .NET 中的相同invoke,但在查找了有关它的信息后,我并没有完全理解为什么需要它。我知道它会调用仿函数和 lambda,但这与它们的直接调用有何不同?能否像.NETstd::invoke中的对应线程那样在特定线程中进行此调用?

c++
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. user7860670
    2020-06-29T16:09:37Z2020-06-29T16:09:37Z

    关键std::invoke是以一致的方式调用类的普通方法和非静态方法。这在编写模板时主要有用。下面是一个紧凑函数模板的示例,它包装了对另一个函数的调用:

    template<typename F, typename V1, typename V2> auto
    foo(F f, V1 v1, V2 v2) -> void
    {
        ::std::invoke(f, v1, v2);
    }
    

    使用示例:

    inline auto
    bar(int v1, int v2) -> void
    {
        ::std::cout << v1 << " " << v2 << ::std::endl;
    }
    
    class Bar
    {
        private: int m_v;
    
        public: explicit
        Bar(int v): m_v{v} {}
    
        public: auto
        bar(int v2) -> void
        {
            ::std::cout << m_v << " " << v2 << ::std::endl;
        }
    };
    
    int
    main()
    {
        int v1{12};
        int v2{23};
        foo(&bar, v1, v2); // вызов обычного метода
        Bar b{12};
        foo(&Bar::bar, b, v2); // вызов нестатического метода класса по ссылке
        foo(&Bar::bar, &b, v2); // вызов нестатического метода класса по указателю
    }
    

    如果不使用::std::invoke它,您将不得不独立实现调用非静态类方法的选项:

    template<typename F, typename V1, typename V2> auto
    foo(F f, V1 v1, V2 v2) -> ::std::enable_if_t
    <
        not ::std::is_member_function_pointer_v<F>
    >
    {
        f(v1, v2);
    }
    
    template<typename F, typename V1, typename V2> auto
    foo(F f, V1 v1, V2 v2) -> ::std::enable_if_t
    <
        ::std::is_member_function_pointer_v<F> and not ::std::is_pointer_v<V1>
    >
    {
        (v1.*f)(v2);
    }
    
    template<typename F, typename V1, typename V2> auto
    foo(F f, V1 v1, V2 v2) -> ::std::enable_if_t
    <
        ::std::is_member_function_pointer_v<F> and ::std::is_pointer_v<V1>
    >
    {
        (v1->*f)(v2);
    }
    
    • 18
  2. Best Answer
    Chorkov
    2020-06-29T15:36:40Z2020-06-29T15:36:40Z

    std::invoke需要统一调用仿函数(包括lambda)、函数指针和类成员函数指针。后者具有与常规函子的语法不匹配的特定调用语法:

    (obj->*mem_fn_ptr)( args... );
    

    如果您正在编写一个 type 的函数std::async,并且您需要实现对所有可调用对象的支持,那么将它们传递到一个包中invoke比为每种情况编写单独的模板实现更容易。这样的语法糖。

    标准中没有.NET 的类似物invoke,因为没有消息处理周期,因此不可能“向线程发送任务”。如果您只需要异步执行,std::async请使用WinAPI函数或窗口库的函数(Qt、wxWidgets ...),或者组织“手动”消息循环并将包装的任务推送到适当的队列中。std::thread

    • 14
  3. Pavel Mayorov
    2020-06-29T15:42:27Z2020-06-29T15:42:27Z

    这与直接调用不同,不是所有可以调用的东西都可以std::invoke直接调用。

    简而言之,该调用std::invoke(f, arg0, args...)尝试进行以下调用之一:

    (arg0.*f)(args...);
    (arg0.get().*f)(args...);
    ((*arg0).*f)(args...);
    arg0.*f
    arg0.get().*f;
    (*arg0).*f;
    f(arg0, args...);
    

    std::invoke当您编写可与任何给定 Callable 对象一起使用的通用代码时,需要使用。

    至于在后台线程中调用函数,为了这些目的发明了一个函数std::async。

    • 12

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5