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

相关推荐
echome88816 小时前
JavaScript Promise 与 async/await 实战:5 个高频异步编程场景的优雅解决方案
开发语言·javascript·ecmascript
Darkwanderor16 小时前
高精度计算——基础模板整理
c++·算法·高精度计算
xcLeigh16 小时前
IoTDB Java 原生 API 实战:SessionPool 从入门到精通
java·开发语言·数据库·api·iotdb·sessionpool
杜子不疼.16 小时前
Java 智能体学习避坑指南:3 个常见误区,新手千万别踩,高效少走弯路
java·开发语言·人工智能·学习
冬天vs不冷16 小时前
为什么 Java 不让 Lambda 和匿名内部类修改外部变量?final 与等效 final 的真正意义
android·java·开发语言
星河耀银海16 小时前
JAVA 多线程编程:从基础原理到实战应用
java·开发语言·php
星河耀银海16 小时前
JAVA IO流:从基础原理到实战应用
java·服务器·开发语言
Tanecious.17 小时前
蓝桥杯备赛:Day5-P1036 选数
c++·蓝桥杯
摸鱼仙人~17 小时前
Math.js 使用教程
开发语言·javascript·ecmascript
mmz120717 小时前
深度优先搜索DFS(c++)
c++·算法·深度优先