0

0

c++的std::invoke和std::apply有什么用? (可调用对象工具)

穿越時空

穿越時空

发布时间:2026-01-11 13:43:02

|

865人浏览过

|

来源于php中文网

原创

std::invoke统一调用语法,支持函数、成员函数指针和数据成员指针;std::apply专用于将tuple元素拆包为独立参数传入可调用对象。

c++的std::invoke和std::apply有什么用? (可调用对象工具)

两者都用于“间接调用可调用对象”,但解决的是完全不同的参数传递场景:std::invoke 解决“怎么把一堆参数原样传给一个可调用对象”,std::apply 解决“怎么把一个 std::tuple 里的元素拆开当参数传”。

std::invoke 用来统一调用语法,屏蔽函数指针/成员函数/成员变量访问的差异

你写 f(a, b) 很自然,但换成成员函数指针、成员变量指针或绑定对象后,语法就乱了——obj.mem_fn(a)(obj.*ptr)(a)obj.mem_data 都不一致。std::invoke 把它们全收口成统一形式。

  • 对普通函数/函数对象:直接转发参数,等价于 f(args...)
  • 对指向成员函数的指针:自动处理对象绑定,支持左值/右值/指针,比如 std::invoke(&MyClass::foo, obj, x)std::invoke(&MyClass::bar, &obj, y)
  • 对指向数据成员的指针:返回该成员的引用,比如 std::invoke(&MyClass::value, obj) 等价于 obj.value
  • 不能用于重载函数名(未取地址),必须是可调用对象或指针;否则编译失败,错误信息通常是 no matching function for call to 'invoke'

std::apply 专为 tuple 拆包设计,把 tuple 元素当独立参数传给可调用对象

当你有一个 std::tuple t,想把它当作三个参数传给 void f(int, std::string, double),不能直接 f(t),也不能手写 f(std::get(t), std::get(t), std::get(t))(类型和长度不固定)。std::apply 就是干这个的。

  • 第一个参数是可调用对象(函数指针、lambda、functor 等),第二个必须是 std::tuple 或其变体(如 std::pair
  • 内部用模板参数推导 + 折叠表达式实现完美转发,所有参数保持原 cv/ref 限定符
  • 如果 tuple 元素个数和可调用对象的参数个数不匹配,编译失败,错误位置通常在 std::apply 调用处,提示类似 no type named 'type' in 'struct std::tuple_element>'
  • 常见搭配:配合 std::make_tuple 或结构化绑定后的打包,用于泛型回调封装或参数转发层
auto t = std::make_tuple(42, std::string("hello"), 3.14);
std::apply([](int i, std::string s, double d) {
    std::cout << i << " " << s << " " << d << "\n";
}, t); // 输出: 42 hello 3.14

别混淆:invoke 不拆 tuple,apply 不处理成员指针

std::invoke 的参数是“扁平列表”,它不关心你传进来的是不是 tuple;std::apply 强制要求第二个参数是 tuple 类型,且只做“解包”这一件事。误用会导致编译器报错类型不匹配,而不是静默错误。

Short AI
Short AI

AI短视频生成器,轻松创作爆款短视频!

下载

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

  • 想调用 func(std::get(t), std::get(t))?用 std::apply(func, t)
  • 想调用 obj.method(x),但 method 是成员函数指针?用 std::invoke(ptr, obj, x)
  • 想调用 std::invoke(func, t)?除非 func 接受一个 std::tuple 参数,否则会编译失败——这不是 invoke 的职责
  • 性能上两者都是零开销抽象:无运行时分支,全部在编译期展开

真正容易被忽略的是 std::invoke 对成员指针的支持细节:它能正确处理 volatileconst 限定的成员函数,也能转发右值对象,但如果你传了一个 const 对象却调用非 const 成员函数,编译器照样报错——它不越权,只做语法桥接。

相关专题

更多
string转int
string转int

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

315

2023.08.02

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

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

520

2023.09.20

string转int
string转int

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

315

2023.08.02

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

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

533

2024.08.29

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

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

51

2025.08.29

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

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

194

2025.08.29

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

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

51

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

98

2025.10.23

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

80

2026.01.09

热门下载

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

精品课程

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

共578课时 | 44.8万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

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

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