C++11 std::function用法
2016-01-27 09:19
495 查看
转自 http://www.hankcs.com/program/cpp/c11-std-function-usage.html
function可以将普通函数,lambda表达式和函数对象类统一起来。它们并不是相同的类型,然而通过function模板类,可以转化为相同类型的对象(function对象),从而放入一个map里。
在看Cocos2d-x的范例代码时,随处可见“很奇怪”的语法:
其中CL是一个宏,对应如下lambda表达式:
#define CL(__className__) [](){ return __className__::create();}
还算好懂,感觉是个工厂模式,同时用宏模拟了接口。
但是这个std::function<Layer*()>却让我少见多怪了,翻开第五版《C++ Primer》,才知道原来是C++11的新特性——可调用对象模板类。一句话说明问题,std::function<Layer*()>代表一个可调用对象,接收0个参数,返回Layer*。
至于function的深入理解,还是用代码说明吧。
如上所示,function可以将普通函数,lambda表达式和函数对象类统一起来。它们并不是相同的类型,然而通过function模板类,可以转化为相同类型的对象(function对象),从而放入一个map里。
另外我实际测试的结果来看,在VS2013编译器下,上述代码可以通过,而第五版《C++ Primer》第512页第一行所言“错误:mod不是一个函数指针”并没有发生错误,有可能是对C++11标准的不同实现吧。
function可以将普通函数,lambda表达式和函数对象类统一起来。它们并不是相同的类型,然而通过function模板类,可以转化为相同类型的对象(function对象),从而放入一个map里。
在看Cocos2d-x的范例代码时,随处可见“很奇怪”的语法:
static std::function<Layer*()> createFunctions[] = { CL(CameraTest1), //... };
其中CL是一个宏,对应如下lambda表达式:
#define CL(__className__) [](){ return __className__::create();}
还算好懂,感觉是个工厂模式,同时用宏模拟了接口。
但是这个std::function<Layer*()>却让我少见多怪了,翻开第五版《C++ Primer》,才知道原来是C++11的新特性——可调用对象模板类。一句话说明问题,std::function<Layer*()>代表一个可调用对象,接收0个参数,返回Layer*。
至于function的深入理解,还是用代码说明吧。
#include <iostream> #include <map> #include <functional> using namespace std; // 普通函数 int add(int i, int j) { return i + j; } // lambda表达式 auto mod = [](int i, int j){return i % j; }; // 函数对象类 struct divide { int operator() (int denominator, int divisor) { return denominator / divisor; } }; ///////////////////////////SubMain////////////////////////////////// int main(int argc, char *argv[]) { // 受限的map map<char, int(*)(int, int)> binops_limit; binops_limit.insert({ '+', add }); binops_limit.insert({ '%', mod }); // 错误 1 error C2664: “void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::insert(std::initializer_list<std::pair<const _Kty,_Ty>>)”: 无法将参数 1 从“initializer-list”转换为“std::pair<const _Kty,_Ty> &&” // binops_limit.insert({ '%', divide() }); // 更灵活的map map<char, function<int(int, int)>> binops = { { '+', add }, { '-', minus<int>() }, { '*', [](int i, int j){return i - j; } }, { '/', divide() }, { '%', mod }, }; cout << binops['+'](10, 5) << endl; cout << binops['-'](10, 5) << endl; cout << binops['*'](10, 5) << endl; cout << binops['/'](10, 5) << endl; cout << binops['%'](10, 5) << endl; system("pause"); return 0; } ///////////////////////////End Sub//////////////////////////////////
如上所示,function可以将普通函数,lambda表达式和函数对象类统一起来。它们并不是相同的类型,然而通过function模板类,可以转化为相同类型的对象(function对象),从而放入一个map里。
另外我实际测试的结果来看,在VS2013编译器下,上述代码可以通过,而第五版《C++ Primer》第512页第一行所言“错误:mod不是一个函数指针”并没有发生错误,有可能是对C++11标准的不同实现吧。
相关文章推荐
- CRC32 c语言 源码
- 使用宏来作为C++单元测试开关
- Leetcode 48 - Rotate Image
- Leetcode 50 - Pow(x, n)
- Leetcode 46 - Permutations
- Leetcode 41 - First Missing Positive
- c++字符串时间加减
- c问题---关于数组溢出的思考
- c++库数学函数
- C++学习 【4.5】 利用函数实现指定的功能---局部变量、全局变量、变量的存储类别、声明和定义
- C++复习(三)
- C++与STL再回顾
- c++类的继承
- [LeetCode] 105 & 106
- C++学习笔记47——继承中的访问权限汇总
- C++入门小程序练习
- C语言链表的简单实用
- VS2013中带命令行参数的调试方法
- C++ stringstream的用法|c++ 字符串流 sstream(常用于格式转换)
- 一起talk C栗子吧(第一百一十三回:C语言实例--线程同步之信号量一)