C++11 std::function用法
转自 http://www.hankcs.com/program/cpp/c11-std-function-usage.html
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['+'](, ) << endl;
cout << binops['-'](, ) << endl;
cout << binops['*'](, ) << endl;
cout << binops['/'](, ) << endl;
cout << binops['%'](, ) << endl;
system("pause");
return ;
}
///////////////////////////End Sub//////////////////////////////////
如上所示,function可以将普通函数,lambda表达式和函数对象类统一起来。它们并不是相同的类型,然而通过function模板类,可以转化为相同类型的对象(function对象),从而放入一个map里。
另外我实际测试的结果来看,在VS2013编译器下,上述代码可以通过,而第五版《C++ Primer》第512页第一行所言“错误:mod不是一个函数指针”并没有发生错误,有可能是对C++11标准的不同实现吧。
C++11 std::function用法的更多相关文章
- C/C++ C++ 11 std::function和std::bind用法
std::bind() std::bind 主要用于绑定生成目标函数,一般用于生成的回调函数,cocos的回退函数都是通过std::bind和std::function实现的.两个点要明白: 1.绑定 ...
- C++ 11 std::function std::bind使用
cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码: auto closeItem = MenuItemImage::create( "CloseNorm ...
- c++11——std::function和bind绑定器
c++11中增加了std::function和std::bind,可更加方便的使用标准库,同时也可方便的进行延时求值. 可调用对象 c++中的可调用对象存在以下几类: (1)函数指针 (2)具有ope ...
- C++11 std::function、std::bind和lambda表达式
参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html 一.关于std::function与std::bin ...
- C++11新特性之二——std::bind std::function 高级用法
/* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com */ #include <iostream> #includ ...
- C++11中的std::function
看看这段代码 先来看看下面这两行代码: std::function<void(EventKeyboard::KeyCode, Event*)> onKeyPressed; std::fun ...
- C++11之std::function和std::bind
std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...
- 【转】C++11中的std::function
原文地址:http://www.jellythink.com/archives/771 看看这段代码 先来看看下面这两行代码: std::function<void(EventKeyboard: ...
- 转 C++11之std::function和std::bind
std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...
随机推荐
- [HDF]hdf-4.2.6类库的使用
HDF文件包括科学数据和VData部分.读取HDF格式的calipso数据,用GDAL可以方便的读取其中的子数据集,但是没有发现GDAL中提供读取Vdata的方法.所以只好考虑借助hdf-4.2.6类 ...
- Jquery 知识表
- UIBarButtonItem变弹簧
UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystem ...
- Codeforce Round #210 Div2
A:对角线为k其他为0 B:利用两个相邻的数一定gcd为1和1与任何数gcd为1错k个位就行了 C:不会做操蛋,好像是因为上一层的始终小于下一层的 好吧C又研究了一下,是个贪心题,不符合的情况先科不考 ...
- poj 题目分类(2)
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj329 ...
- git的基本使用
1.在本地新建一个文件夹来存放代码 2.用命令行进入这个文件夹 3.git init --来创建一个代码仓库 3. 配置用户信息:用户名和 邮箱(联系作者本人沟通, 责任到人) git config ...
- [转] java书籍(给Java程序猿们推荐一些值得一看的好书 + 7本免费的Java电子书和教程 )
7本免费的Java电子书和教程 1. Thinking in Java (Third Edition) 本书的作者是Bruce Eckel,它一直都是Java最畅销的免费电子书.这本书可以帮助你系统的 ...
- webDriver中的alert
driver.switchTo().alert();这句可以得到alert\confirm\prompt对话框的对象,然后运用其方法对它进行操作.对话框操作的主要方法有: getText() ...
- CS2013调试DLL
需要打开两个项目,一个是Win32Project1,由这个项目创建DLL,注意要在DLL函数前加上__declspec(dllexport),这样就会还配套生成一个.lib 然后再打开一个项目,一般为 ...
- demo15 AlertDialog
Dialog dialog = new AlertDialog.Builder(this).setTitle("对话框").setMessage("this is msg ...