C++11 std::function

可调用对象

可调用对象,是可以被调用的实体。

通俗来说:x(...)

满足以下条件之一即可

  • 普通函数 / 静态成员函数
  • 函数指针 (Ret(*)(Args...))
  • 成员函数指针 (Ret (C::*)(Args...),调用方式特殊)
  • lambda 表达式对象(本质是编译器生成的类对象)
  • 函数对象 / 仿函数(functor) :定义了 operator() 的类/对象
  • std::function:类型擦除后的可调用包装器
  • std::bind 结果(C++11 起,可调用)

std::function

头文件:#include <functional>
std::function 本质上是一个类型擦除的包装器,统一存放和管理各种类型的可调用对象。

函数签名

cpp 复制代码
template< class >  
class function; /* undefined */

template< class R, class... Args >  
class function<R(Args...)>;

要求里面的 callable 能以 Args... 调用,并且返回值能转成 R。

基本用法

cpp 复制代码
// 普通函数 || 函数指针
int add(int a, int b) {return a + b;}

function<int(int, int)> f = add;
int x = f(1, 2);

// lambda 
function<int(int)> f = [](int x){ return ++x; };
int x = f(5);

// 仿函数
struct Mul {
  int operator()(int a, int b) const { return a * b; }
};

function<int(int,int)> h = Mul{};
int z = h(2, 3); // 6

进阶用法

类型擦除带来的统一接口。

这里使用 function 可以放入相同函数类型的不同类型

回调列表
cpp 复制代码
int add(int a, int b) {return a + b;}

struct Mul {
  int operator()(int a, int b) const { return a * b; }
};

vector<function<int(int,int)>> v;
v.push_back(add);
v.push_back(Mul{});

for (auto e : v) {
	e(10, 3);
}
回调参数
cpp 复制代码
void run(std::function<int(int)> op) {
  int r = op(10);
}

run([](int x){ 
	return x * x; 
});

注意事项

空状态

std::function 可以是"空的":

如果对空的 std::function 直接调用,会抛:

  • std::bad_function_call
cpp 复制代码
std::function<void()> f; 
if (!f) { /* 空 */ }

try { 
	f(); 
} catch (const std::bad_function_call&) {
	// ...
}

std::function 绑定安全

相关推荐
starzy19905 分钟前
深入理解Scala可变Map:动态构建场景下的性能与设计权衡
开发语言·scala
zhanghaha13141 小时前
C# 系列教程_7 判断语句(分支)保姆级精讲
开发语言·c#
apcipot_rain1 小时前
C++转Java日记(02)
java·开发语言·c++
杜 硕2 小时前
从零开始的C++生活——第七讲——02
开发语言·c++·生活
zhanghaha13142 小时前
C# 系列教程_8 循环语句 保姆级精讲(面向新手)
开发语言·c#
Rabitebla10 小时前
【Linux 底层原理】进程(十):进程等待详解---从僵尸进程到 wait、waitpid 与 status
linux·c++·笔记·学习·visual studio
麦麦麦当劳大王10 小时前
【油猴脚本】Boss直聘 岗位职责复制
开发语言·前端·javascript
starzy199010 小时前
深入理解Scala Map:从实现原理到工程实践
开发语言·后端·scala
只睡四小时11 小时前
Three.js Sub-tick:漏判 60.7%→0
开发语言·javascript·性能优化·ecmascript·游戏开发·three.js·碰撞检测
码农小河6612 小时前
基于SSM+JSP的高校专业信息管理系统【附源码+数据库】
java·开发语言·数据库