定义
c++中函数是实现代码模块化和复用的基本单元
c++11引入通用多态函数包装器std::function, 能实现类似函数指针功能, 可以存储、复制和调用任何可调用对象, 如函数、函数指针、lambda表达式、仿函数等
#include <functional>
std::function<返回类型(参数...)>
- 示例, 接受两个 int 参数并返回 void 类型function
std::function<void(int, int)> func;
操作
绑定普通函数
将普通函数绑定到 std::function 对象中, 并通过该对象调用函数
#include <iostream>
#include <functional>
int add(int a, int b) {
return a + b;
}
int main() {
std::function<int(int, int)> func = add;
std::cout << "add(2, 3) = " << func(2, 3) << std::endl;
std::cout << "add(4, 5) = " << func(4, 5) << std::endl;
return 0;
}
运行结果
add(2, 3) = 5
add(4, 5) = 9
绑定lambda表达式
std::function 还可以绑定到 lambda 表达式, lambda 表达式可以直接在定义时提供功能而不需要额外的命名
#include <iostream>
#include <functional>
int main() {
std::function<int(int, int)> multiply = [](int a, int b) { return a * b; };
std::cout << "multiply(2, 3) = " << multiply(2, 3) << std::endl;
return 0;
}
绑定成员函数
当需要绑定类成员函数时, 可结合使用 std::bind std::function, 同时需传递类对象实例
std::bind 用于将类成员函数与特定实例绑定, std::placeholders::_1 和 std::placeholders::_2 表示函数参数占位符
#include <iostream>
#include <functional>
class Calculator {
public:
int subtract(int a, int b) const {
return a - b;
}
};
int main() {
Calculator calc;
std::function<int(int, int)> func = std::bind(&Calculator::subtract, calc, std::placeholders::_1, std::placeholders::_2);
std::cout << "subtract(5, 2) = " << func(5, 2) << std::endl;
return 0;
}
运行结果
subtract(5, 2) = 3
使用仿函数(函数对象)
仿函数是实现了operator()的类或结构体对象, 可以像普通函数一样被调用
#include <iostream>
#include <functional>
struct Divide {
int operator()(int a, int b) const {
return a / b;
}
};
int main() {
Divide divide;
std::function<int(int, int)> func = divide;
std::cout << "divide(6, 2) = " << func(6, 2) << std::endl;
return 0;
}
作为回调函数
std::function 还常用于回调函数的实现
回调函数允许动态地改变行为, 可以用于事件驱动编程、异步编程等场景
#include <iostream>
#include <functional>
void process(const std::function<void(int)>& call_back) {
for (int i = 0; i < 5; ++i) {
call_back(i);
}
}
int main() {
process([](int value) {
std::cout << "processing value: " << value << std::endl;
});
return 0;
}
运行结果
processing value: 0
processing value: 1
processing value: 2
processing value: 3
processing value: 4
std::function 可存储所有符合指定函数签名的可调用对象, 但存储对象类型必须与 std::function 签名相同
当 std::function 不指向任何可调用对象时, 其值为 nullptr, 可以使用 if 判断其有效性
特性
可存储任何可调用对象
std::function 可以存储多种类型的可调用对象, 包括函数指针、lambda 表达式、成员函数、仿函数等, 提供了高度的灵活性
使得能够使用统一的接口来操作不同类型的函数
空函数对象
当 std::function 不指向任何可调用对象时, 它的值为 nullptr
因此使用 std::function 时应该检查其是否有效:
std::function<void()> func;
if (func) {
func(); // 调用
} else {
std::cout << "No function assigned!" << std::endl;
}
性能
std::function的灵活性和通用性也带来了一定的性能开销, 特别是在运行时类型擦除(type erasure)和动态分配内存时
因此如果性能要求较高, 且函数类型已知, 使用普通函数指针或其他低开销的方式可能更合适