0

0

C++中std::invoke怎么调用可调用对象_C++17统一调用语法解析【现代】

尼克

尼克

发布时间:2026-02-13 14:03:01

|

326人浏览过

|

来源于php中文网

原创

std::invoke 是 c++17 引入的统一调用工具,支持普通函数、成员函数/变量指针、lambda、函数对象等;它解决不同可调用对象调用语法不一致的问题,自动识别类型并正确分发,避免手动编写多套调用逻辑。

c++中std::invoke怎么调用可调用对象_c++17统一调用语法解析【现代】

std::invoke 是什么,为什么需要它

std::invoke 是 C++17 引入的工具函数,用于统一调用各类可调用对象:普通函数、成员函数指针、成员变量指针、函数对象(含 lambda)、绑定表达式等。它解决了“同一种调用逻辑要写多套代码”的问题——比如你不能直接对 std::mem_fn(&X::f)&X::data 使用 () 调用,但 std::invoke 可以。

常见错误现象:

  • 对成员函数指针直接 pf(obj, args...) 编译失败(必须用 .<em></em>->
  • 对成员变量指针试图 pm(obj) 报错:“expression must have (pointer-to-) function type”
  • std::bind 包装后又想加参数,容易误传或类型不匹配

std::invoke 内部自动识别目标类型并选择正确调用方式,省去手动分发逻辑。

怎么用 std::invoke:参数规则和典型场景

std::invoke 的签名是:template<class f class... args> auto invoke(F&& f, Args&&... args)</class>。关键在于它如何解析 fargs

立即学习C++免费学习笔记(深入)”;

  • f 是指向成员函数的指针 → 第一个 args 必须是对象(或其引用/指针),其余为成员函数参数
  • f 是指向成员变量的指针 → 第一个 args 同样必须是对象(或其引用/指针),且不能有额外参数
  • f 是普通可调用对象(函数、lambda、functor)→ 直接转发所有 args

使用示例:

struct S { int x = 42; void f(int a) { } };
S s;
<p>std::invoke(&S::f, s, 100);     // ✅ 成员函数:对象 + 参数
std::invoke(&S::x, s);          // ✅ 成员变量:只传对象
std::invoke([](int a){}, 5);    // ✅ lambda
std::invoke(std::plus<>{}, 1, 2);// ✅ 函数对象</p>

注意:传入的对象不能是临时对象 + 成员函数指针组合(除非该成员函数是 const 限定的),否则可能因绑定到右值而编译失败。

简篇AI排版
简篇AI排版

AI排版工具,上传图文素材,秒出专业效果!

下载

std::invoke 和 std::invoke_r 的区别

std::invoke_r 是 C++23 新增的配套函数,用于显式指定返回类型,避免模板推导歧义或强制转换需求:

  • std::invoke(f, ...) 返回类型由调用表达式自然推导
  • std::invoke_r<r>(f, ...)</r> 强制返回 R 类型(通过 static_cast 或隐式转换)

典型适用场景:

  • 调用返回 void 的函数,但你希望统一处理为某个占位值(如 std::invoke_r<int>(f)</int> 不合法,但 std::invoke_r<void>(f)</void> 合法)
  • 避免 ADL 干扰或推导出意外的引用类型(例如返回 int& 但你需要 int 值)
  • 在 requires 表达式中约束返回类型

目前大多数项目仍用 C++17/20,std::invoke_r 尚未普及,但若你已启用 C++23,它比在 std::invoke 外包一层 static_cast 更清晰安全。

容易被忽略的细节:完美转发与生命周期

std::invoke 对所有参数做完美转发,这意味着:

  • 如果你传入一个临时对象(如 std::string{"hello"})给成员函数指针,它会被移动或复制,取决于目标函数签名
  • 若目标是 const S& 成员函数,传入临时 S{} 是允许的;但非 const 成员函数则不允许绑定到临时对象

更隐蔽的问题是:

  • std::invoke(&S::f, std::move(s), 1) 合法,但之后 s 可能处于有效但未定义状态(取决于 S::f 是否为移动感知)
  • std::shared_ptr<s></s> 调用时,std::invoke(&S::f, ptr, ...) 会增加一次引用计数(因为 ptr 被转发为左值);而 std::invoke(&S::f, *ptr, ...) 则不会

这些行为不是 bug,而是完美转发的必然结果——用之前得确认参数的值类别和目标函数的 cv/ref 限定。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

709

2023.08.02

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

543

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

709

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

561

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

206

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

181

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

114

2025.11.27

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

8

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.3万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号