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 绑定安全

相关推荐
逻极7 小时前
pytest 入门指南:Python 测试框架从零到一(2025 实战版)
开发语言·python·pytest
你的冰西瓜7 小时前
C++ STL算法——排序和相关操作
开发语言·c++·算法·stl
今儿敲了吗8 小时前
29| 高考志愿
c++·笔记·学习·算法
海边的Kurisu8 小时前
Mybatis-Plus | 只做增强不做改变——为简化开发而生
java·开发语言·mybatis
浅念-8 小时前
C++ 模板进阶
开发语言·数据结构·c++·经验分享·笔记·学习·模版
紫陌涵光9 小时前
77. 组合
c++·算法·leetcode·深度优先
Omigeq9 小时前
1.2.2 - 采样搜索算法(以RRT和RRT*为例) - Python运动规划库教程(Python Motion Planning)
开发语言·人工智能·python·机器人
m0_5312371710 小时前
C语言-操作符进阶
c语言·开发语言
q12345678909810 小时前
FNN sin predict
开发语言·python
沐知全栈开发10 小时前
C++ 多态
开发语言