C++11 function使用
function是一组函数对象包装类的模板,实现了一个泛型的回调机制。
引入头文件
#include <functional>
using namespace std;
using namespace std::placeholders; //bind的时候会用`
参考:http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html
fuction bind:http://blog.csdn.net/fjb2080/article/details/7527715
我们可以调用的对象有很多,比如普通函数、函数指针、lanmbda表达式、函数对象和类的成员函数等。
不管采用哪种方式,主要调用形式一样(返回值类型、传递给调用的实参类型),我们就可以使用同一种形式来调用。
这个时候就可以用到function模板,它给予我们在调用的方式上更大的弹性。
请看一下三种不同的函数定义:
- int add(int a, int b){
- return a+b;
- }
- auto mod=[](int a, int b){return a%b;};
- struct divide{
- int operator()(int m, int n){
- return m/n;
- }
- };
这三种都可以使用同一种调用形式,int(int, int),调用方式如下:
- function<int(int,int)> func1= add;
- function<int(int,int)> func2= divide();
- function<int(int,int)> func3= mod;
- cout<<func1(5, 6)<<endl;
- cout<<func2(5, 6)<<endl;
- cout<<func3(5, 6)<<endl;
学会了使用function,可以继续如下进行抽象定义,不同类型采用相同的调用方法:
- map<string,function<int(int, int)>> funs =
- {
- {"+", add},
- {"-", std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客
- {"/", divide()},//类成员函数
- {"*", [](int i,int j){return i*j;}},//lambda表达式
- {"%", mod},
- };
- funs["+"](4,6);
以上就是function的简单使用。下面是从另一篇博客转载的,使用function的引用来保存函数对象。考虑下面代码:
- class CAdd
- {
- public:
- CAdd():m_nSum(0){NULL;}
- int operator()(int i)
- {
- m_nSum += i;
- return m_nSum;
- }
- int Sum() const
- {
- return m_nSum;
- }
- private:
- int m_nSum;
- };
- int main(int argc, const char * argv[])
- {
- CAdd cAdd;
- function<int(int)> funcAdd1 = cAdd;
- function<int(int)> funcAdd2 = cAdd;
- cout<<funcAdd1(10)<<endl;
- cout<<funcAdd2(10)<<endl;
- cout<<cAdd.Sum()<<endl;
- return 0;
- }
上面的输出结果是 10 10 0。我们将同一个函数对象赋值给了两个function,然后分别调用这两个function,但函数中的成员变量的值没有保存,问题在哪里?因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1,f2中保存的都是cAdd对象的拷贝。
C++11提供了ref和cref函数来提供对象的引用和常引用的包装。要是function能够正确保存函数对象的状态,可以如下修改代码:
- function<int(int)> funcAdd3 = ref(cAdd);
- function<int(int)> funcAdd4 = ref(cAdd);
- cout<<funcAdd3(10)<<endl;
- cout<<funcAdd4(10)<<endl;
- cout<<cAdd.Sum()<<endl;
另外,两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝。如果源function保存的是对函数对象的引用,则目标function保存的也是函数对象的引用。
C++11 function使用的更多相关文章
- C++11 Function 使用场景
[1]场景分析 在一个函数内部,可能会多次用到某一段代码,一般情况是把这段用到次数较多的代码封装成一个函数. 但是,如果这段代码仅仅只在这个函数中有使用,这时封装成函数显得既麻烦又冗赘. 那么,有没有 ...
- Using C++11 function & bind
The example of callback in C++11 is shown below. #include <functional> void MyFunc1(int val1, ...
- C++11 function
#include <iostream> #include <functional> #include <vector> using namespace std; / ...
- c++11 function bind 测试。
实验小结 1)function 是一个模板类.有函数指针成员.可以看作安全型函数指针. template<typename _Res, typename... _ArgTypes> cla ...
- c++11:function的用法
function是函数.函数对象.函数指针.和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针 普通函数 #include <functional> voi ...
- C++ 11: function & bind 使用示例
#include <functional> #include <iostream> struct Foo { Foo(int num) : num_(num) {} void ...
- C++11 function用法 可调用对象模板类
std::function<datatype()> ()内写参数类型 datatype 代表function的返回值 灵活的用法.. 代码如下 #include <stdio.h&g ...
- C++11绑定器bind及function机制
前言 之前在学muduo网络库时,看到陈硕以基于对象编程的方式,大量使用boost库中的bind和function机制,如今,这些概念都已引入至C++11,包含在头文件<functional&g ...
- JavaScript function函数种类(转)
转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...
随机推荐
- JPQL 的基本使用
一.概念 JPQL 语言,即 Java Persistence Query Language 的简称.JPQL 和 HQL 是非常类似的,支持以面向对象的方式来写 SQL 语句,当然也支持本地的 SQ ...
- 一个小demo熟悉Spring Boot 和 thymeleaf 的基本使用
目录 介绍 零.项目素材 一. 创建 Spring Boot 项目 二.定制首页 1.修改 pom.xml 2.引入相应的本地 css.js 文件 3.编辑 login.html 4.处理对 logi ...
- C++ Error C2662 cannot convert 'this' pointer from 'const *'
---恢复内容开始--- 这个错误在于一点:常量对象只能调用常量成员(函数\变量),不能调用非常量成员.另一方面,非常量对象,既可以调用常量成员,又可以调用非常量成员. class A { publi ...
- Linux之iptables(六、rich规则)
其它规则 当基本firewalld语法规则不能满足要求时,可以使用以下更复杂的规则 rich-rules 富规则,功能强,表达性语言 Direct configuration rules 直接规则,灵 ...
- PHP代码静态分析工具PHPStan
最近发现自己写的PHP代码运行结果总跟自己预想的不一样,排查时发现大多是语法错误,在运行之前错误已经种下.可能是自己粗心大意,或者说php -l检测太简单,不过的确是有一些语法错误埋藏得太深(毕竟PH ...
- Python基础(五)集合与函数
一.Set集合 set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key.下面一起看一下set的定义和使用方法: (一),set定义 1 ...
- orcad中注意的事情
1.地的标识不能放到已经分配了网络的线上. 在用orcad画原理图的时候,把电源放到网络的时候需要特别的注意,如果,将电源地直接放到线上,而这根线又已经被分配了网络标号,那这个地会随已经分配了的网络号 ...
- 团队开发git使用各种问题
参考:https://www.cnblogs.com/schaepher/p/4933873.html 问题-3:保持github上项目干净,对于在不同机器上运行会不同的文件不予维护(如.idea/w ...
- [luoguP2863] [USACO06JAN]牛的舞会The Cow Prom(Tarjan)
传送门 有向图,找点数大于1的强连通分量个数 ——代码 #include <stack> #include <cstdio> #include <cstring> ...
- Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes
D. Prefixes and Suffixes You have a string s = s ...