C++17 新特性_第二章 C++17标准库特性_std::invoke和std::invoke_result_t

本文记录C++17新特性之invoke和invoke_result_t.

文章目录

  • [第2章 C++17标准库特性](#第2章 C++17标准库特性)
    • [2.9 std::invoke](#2.9 std::invoke)
      • [2.9.1 invoke作用](#2.9.1 invoke作用)
      • [2.9.2 使用举例](#2.9.2 使用举例)
      • [2.9.3 invoke 和 function对比](#2.9.3 invoke 和 function对比)
    • [2.10 std::invoke_result_t](#2.10 std::invoke_result_t)

第2章 C++17标准库特性

2.9 std::invoke

C++17之前,编写泛型代码处理回调时,调用不同的"可调用对象"(普通函数、函数指针、成员函数指针、以及仿函数(Functors)和 Lambda 表达式)时,需要不同的调用形式:

  • 对于普通函数/Lambda/函数对象,直接调用f(args...)
  • 对于成员函数指针,调用方式,(obj.*f)(args...) 或 (ptr->*f)(args...)
    针对这种不一致的调用,在实现时,需要使用SFINAE模板元代码区别这些情况。

C++17 将这种复杂的逻辑标准化为 std::invoke,让普通开发者也能轻松编写通用的回调逻辑。

2.9.1 invoke作用

invoke包含在 中,核心作用:以统一的语法调用任何可调用对象。

2.9.2 使用举例

示例1:invoke调用不同的可调用对象。

cpp 复制代码
    // 1. 普通函数
    void printNum(int i) {
        std::cout << "Function: " << i << std::endl;
    }

    // 2. 仿函数 (Functor)
    struct Printer {
        void operator()(int i) const {
            std::cout << "Functor: " << i << std::endl;
        }
    };

    // 3. 类成员
    struct Foo {
        int value = 100;
        void print(int i) {
            std::cout << "Member Function: " << i + value << std::endl;
        }
    };

    void test()
    {
        // 调用普通函数
        std::invoke(printNum, 10);
        // Function: 10

        // 调用 Lambda
        std::invoke([](int i) { std::cout << "Lambda: " << i << std::endl; }, 20);
        // Lambda: 20
        
        // 调用仿函数
        Printer p;
        std::invoke(p, 30);
        // Functor: 30
        
        // 调用成员函数 (注意:第一个参数必须是对象实例或指针)
        Foo f;
        std::invoke(&Foo::print, f, 40);  // 传对象
        std::invoke(&Foo::print, &f, 50); // 传指针
       //Member Function : 140
       //     Member Function : 150
    }

示例2:编写一个函数执行器,可执行任何函数。

cpp 复制代码
    // decltype(auto) 返回值
    template<typename Callable,typename ...Args>
    decltype(auto) logAndExecute(Callable&& func, Args &&...args)
    {

        // 使用invoke 统一调用
        if constexpr (std::is_void_v<  std::invoke_result_t<Callable, Args...> >)
        {
			std::invoke(std::forward<Callable>(func), std::forward<Args>(args)...);
			cout << "函数返回void类型,无返回值可打印。" << endl;
        }
        else
        {
			decltype(auto) ret = std::invoke(std::forward<Callable>(func), std::forward<Args>(args)...);
            return ret;
        }
    }

    struct Worker
    {
        void dowork(int id)
        {
            std::cout << "Working on " << id << std::endl;
        }
    };

    void test()
    {
		// 1 调用普通函数
        auto result = logAndExecute([](int x, int y) {
            return x + y;
            }, 10, 20);
        std::cout << "Result: " << result << std::endl;
        // Result: 30
        
        // 2 调用成员函数
        Worker w;
        logAndExecute(&Worker::dowork, &w, 42);
		// Working on 42
    }

2.9.3 invoke 和 function对比

std::function 是一个"容器":用于存储可调用对象,以便在未来某个时刻调用。它涉及类型擦除和运行时开销。

std::invoke 是一个"动作":用于立即执行可调用对象,统一调用语法。它通常用于泛型编程,零运行时开销。

2.10 std::invoke_result_t

见 模板与泛型编程笔记。

https://blog.csdn.net/weixin_43916755/article/details/155234300

相关推荐
YYYing.4 小时前
【Linux/C++进阶篇(二) 】超详解自动化构建 —— 日常开发中的“脚本” :Makefile/CMake
linux·c++·经验分享·ubuntu
范纹杉想快点毕业4 小时前
嵌入式实时系统架构设计:基于STM32与Zynq的中断、状态机与FIFO架构工程实战指南,基于Kimi设计
c语言·c++·单片机·嵌入式硬件·算法·架构·mfc
玖釉-4 小时前
核心解构:Cluster LOD 与 DAG 架构深度剖析
c++·windows·架构·图形渲染
程序员敲代码吗4 小时前
C++运行库修复指南:解决游戏办公软件报错问题
开发语言·c++·游戏
孞㐑¥4 小时前
算法—哈希表
开发语言·c++·经验分享·笔记·算法
近津薪荼5 小时前
递归专题(2)——合并链表
c++·学习·算法·链表
maplewen.5 小时前
C++11 std::function
开发语言·c++
水饺编程5 小时前
第4章,[标签 Win32] :文本尺寸的度量
c语言·c++·windows·visual studio
蒹葭玉树5 小时前
【C++上岸】C++常见面试题目--操作系统篇(第二十九期)
java·c++·面试
浅念-5 小时前
C语言——自定义类型:结构体、联合体、枚举
c语言·开发语言·数据结构·c++·笔记·学习·html