C++11中万能的可调用类型声明std::function<...>
在C++11中,callable object 包括传统C函数,C++成员函数,函数对象(实现了()运算符的类的实例),lambda表达式(特殊函数对象)共4种。程序设计,特别是程序库设计时,经常需要涉及到回调,如果针对每种不同的callable object单独进行声明类型,代码将会非常散乱,也不灵活。如下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #include <iostream> #include <functional> using namespace std; // 传统C函数 int c_function( int a, int b) { return a + b; } // 函数对象 class Functor { public : int operator()( int a, int b) { return a + b; } }; int main( int argc, char ** argv) { int (*f)( int , int ); // 声明函数类型,赋值只能是函数指针 f = c_function; cout << f(3, 4) << endl; Functor ff = Functor(); // 声明函数对象类型,赋值只能是函数对象 cout << ff(3, 4) << endl; }幸运的是,C++标准库的头文件里定义了std::function<>模板,此模板可以容纳所有类型的callable object.示例代码如下:#include <iostream> #include <functional> using namespace std; // 传统C函数 int c_function( int a, int b) { return a + b; } // 函数对象 class Functor { public : int operator()( int a, int b) { return a + b; } }; int main( int argc, char ** argv) { // 万能可调用对象类型 std::function< int ( int , int )> callableObject; // 可以赋值为传统C函数指针 callableObject = c_function; cout << callableObject(3, 4) << endl; // 可以赋值为函数对象 Functor functor; callableObject = functor; cout << callableObject(3, 4) << endl; // 可以赋值为lambda表达式(特殊函数对象) callableObject = []( int a, int b){ return a + b; }; cout << callableObject(3, 4) << endl; }#include <iostream> #include <functional> #include <list> using namespace std; // 传统C函数 int c_function( int a, int b) { return a + b; } // 函数对象 class Functor { public : int operator()( int a, int b) { return a + b; } }; int main( int argc, char ** argv) { Functor functor; std::list<std::function< int ( int , int )>> callables; callables.push_back(c_function); callables.push_back(functor); callables.push_back([]( int x, int y)-> int { return x + y; }); for ( const auto & e : callables) { cout << e(3, 4) << endl; } } |
std::function<>的这种多态能力确实很强,这样可以定义一个回调列表,而列表的元素可接受的可调用物类型并不相同。如下:
对于使用C回调机制的程序库来说,C++的std::function<>能兼容传统C函数指针,所以库这一端使用std::function<>代替函数指针,并不会影响旧有客户端程序的编码方式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」