1. 函数作用
boost::function
是 Boost 库提供的一个 通用函数封装器,可用于存储、传递和调用任意可调用对象(如普通函数、函数指针、Lambda、函数对象、成员函数指针等)。它类似于 C++11 及以上标准的 std::function
。
作用总结:
- 可以存储不同类型的可调用对象。
- 可以实现回调机制。
- 提供类型安全的函数调用接口。
- 允许运行时动态绑定函数。
2. 函数原型
boost::function
是模板类,其基本形式为:
template<typename Signature>
class boost::function;
其中 Signature
是函数签名,形式为:
RetType(ArgTypes...)
例子:
boost::function<int(int, int)> func;
表示 func
可以存储任何返回 int
,参数为两个 int
的函数。
3. 参数说明
Signature
:函数签名,指定返回类型和参数类型。赋值对象:
- 普通函数指针
- 函数对象(重载
operator()
的类) - Lambda 表达式
- 成员函数指针(需要绑定实例或使用
boost::bind
)
4. 使用步骤
- 包含头文件
#include <boost/function.hpp>
#include <boost/bind/bind.hpp> // 如果需要绑定成员函数
- 声明函数对象
boost::function<返回类型(参数类型...)> func;
- 赋值可调用对象
func = 普通函数指针;
func = lambda表达式;
func = 函数对象;
func = boost::bind(&类::成员函数, 对象, _1, _2);
- 调用函数
func(arg1, arg2);
5. 代码示例
示例 1:普通函数
#include <iostream>
#include <boost/function.hpp>
int add(int a, int b) {
return a + b;
}
int main() {
boost::function<int(int, int)> func = add;
std::cout << "3 + 5 = " << func(3, 5) << std::endl;
return 0;
}
示例 2:Lambda 表达式
boost::function<int(int,int)> func = [](int a, int b){ return a*b; };
std::cout << "3*5 = " << func(3,5) << std::endl;
示例 3:函数对象
struct Multiply {
int operator()(int a, int b) {
return a * b;
}
};
boost::function<int(int,int)> func = Multiply();
std::cout << func(4,5) << std::endl;
示例 4:成员函数
struct MyClass {
int add(int a, int b) { return a + b; }
};
MyClass obj;
boost::function<int(int,int)> func = boost::bind(&MyClass::add, &obj, _1, _2);
std::cout << func(10, 20) << std::endl;
6. 关键注意事项
类型匹配严格
boost::function
的函数签名必须与被赋值对象完全匹配。
可为空
- 默认构造的
boost::function
对象为空,可通过func.empty()
检查。 - 调用空函数对象会抛出异常
boost::bad_function_call
。
- 默认构造的
性能开销
boost::function
支持类型擦除,因此存在一定的运行时开销。
拷贝与赋值
- 支持拷贝构造和赋值操作,但内部实现是深拷贝。
7. 高级用法
- 结合
boost::bind
绑定参数
boost::function<int(int)> func = boost::bind(add, 5, _1);
std::cout << func(10); // 输出 15
- 存储不同类型的函数
boost::function<void()> f;
f = [](){ std::cout << "Lambda\n"; };
f();
f = [](){ std::cout << "Another Lambda\n"; };
f();
- 回调机制
void process(boost::function<void(int)> callback) {
for(int i=0;i<3;i++)
callback(i);
}
process([](int n){ std::cout << n << "\n"; });
- 与多态结合
- 可以存储不同类成员函数,但签名相同。
- 可实现策略模式或事件驱动系统。
总结:
boost::function
是一种 类型安全、可存储任意可调用对象的函数封装器,常用于回调、事件系统和动态绑定场景。在 C++11 及以上,std::function
提供了完全相同的功能,但 boost::function
在老项目或对 Boost 特性依赖时仍然非常实用。
8. 实际应用场景实例
下面是一些boost::function
的实际应用场景实例**,覆盖回调、事件系统、策略模式、多态调用等,既有基础也有高级用法。
1. GUI 或事件回调
在事件驱动程序中,boost::function
可以存储回调函数:
#include <iostream>
#include <boost/function.hpp>
#include <vector>
class Button {
public:
boost::function<void()> onClick;
void click() {
if(onClick) onClick(); // 调用回调
}
};
int main() {
Button btn;
btn.onClick = [](){ std::cout << "Button clicked!\n"; };
btn.click(); // 输出: Button clicked!
// 可以动态修改回调
btn.onClick = [](){ std::cout << "Another action!\n"; };
btn.click(); // 输出: Another action!
}
应用场景:GUI、事件驱动系统、信号槽机制。
2. 数学计算策略模式
可以动态替换算法,实现策略模式:
#include <iostream>
#include <boost/function.hpp>
double add(double a, double b) { return a + b; }
double multiply(double a, double b) { return a * b; }
int main() {
boost::function<double(double,double)> strategy;
strategy = add;
std::cout << "Add: " << strategy(3,5) << std::endl; // 8
strategy = multiply;
std::cout << "Multiply: " << strategy(3,5) << std::endl; // 15
}
应用场景:动态选择算法或处理策略,如金融计算、图像处理算法选择。
3. 成员函数绑定
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind/bind.hpp>
struct Printer {
void printNumber(int n) { std::cout << "Number: " << n << std::endl; }
};
int main() {
Printer p;
boost::function<void(int)> func = boost::bind(&Printer::printNumber, &p, _1);
func(42); // 输出: Number: 42
}
应用场景:将类成员方法作为回调或任务传递,常见于任务调度、异步操作。
4. 异步任务调度
结合任务队列或线程池使用:
#include <iostream>
#include <boost/function.hpp>
#include <vector>
#include <thread>
void asyncTask(boost::function<void()> task) {
std::thread t([task](){ task(); });
t.detach();
}
int main() {
boost::function<void()> task = [](){ std::cout << "Task executed asynchronously\n"; };
asyncTask(task);
std::this_thread::sleep_for(std::chrono::seconds(1)); // 等待任务执行
}
应用场景:线程池、异步任务、事件回调系统。
5. 参数绑定与偏函数
利用 boost::bind
绑定部分参数:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind/bind.hpp>
int compute(int a, int b, int c) {
return a + b * c;
}
int main() {
boost::function<int(int,int)> func = boost::bind(compute, 2, _1, _2);
std::cout << func(3,4) << std::endl; // 输出: 2 + 3*4 = 14
}
应用场景:任务预配置、偏函数应用、参数固定化。
6. 多态回调
存储不同类对象的成员函数,只要签名一致:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind/bind.hpp>
struct A {
void say() { std::cout << "Hello from A\n"; }
};
struct B {
void say() { std::cout << "Hello from B\n"; }
};
int main() {
boost::function<void()> func;
A a; B b;
func = boost::bind(&A::say, &a); func(); // 输出: Hello from A
func = boost::bind(&B::say, &b); func(); // 输出: Hello from B
}
应用场景:动态选择对象方法、插件系统、策略切换。
7. 数值计算回调
用于迭代、求根或积分函数传入回调:
#include <iostream>
#include <boost/function.hpp>
#include <cmath>
double integrate(boost::function<double(double)> f, double a, double b, int n) {
double step = (b-a)/n;
double sum = 0;
for(int i=0;i<n;i++)
sum += f(a + i*step) * step;
return sum;
}
int main() {
auto f = [](double x){ return std::sin(x); };
std::cout << "Integral of sin(x) from 0 to pi: "
<< integrate(f, 0, 3.1415926, 1000) << std::endl;
}
应用场景:数值计算、优化算法、回调式计算。