c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind
一、符号修饰与函数签名
1、符号修饰
编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名。GCC的C++符号修饰方法如下:
1)所有符号都以_z开头
2)名字空间的名字
名字空间(或类)的名字前加上N
名字前还有一个数字,是名字的字符数。比如1C,1是C的长度。
3)函数名
与名字空间一样,函数名前也有数字,比如4func,4是func的字符数。
4)参数
参数以E开头
例子
N::C::func(int) 的函数签名经过修饰为_ZN1N1C4funcEi
2、函数签名
函数签名组成部分:包括函数名,参数类型,参数个数和顺序,以及它所在类和命名空间。
以上任何一个部分的不同,都会导致符号修饰后的名词不同,即导致函数签名不同,故可以区分不同的函数,在调用的时候就不会出错。
二、函数指针
例子: int(*p)(int,int)
语句定义了一个指向函数的指针变量P,这个函数指针可以指向这么一个函数,即返回值为int类型,且有两个int参数的函数,指针p的类型为int(*)(int,int)。
函数指针的统一定义方式为:
函数返回类型(* 指针变量名)(函数参数列表)
简单用法:
int func(int x); //定义一个函数
int (*p)(int x); //定义一个函数指针
p=func; //将函数func的首地址赋值给指针变量p
三、c++11中的匿名函数(lambda函数,lambda表达式)
C++11提供了对匿名函数的支持,称为lambda函数(也成为lambda表达式),形式如下
[capture](parameters)->return-type{body}
解析:
capture
1)、[] //未定义变量,试图在lambda函数内使用任何外部变量都是错误的
2)、[x,&y] //x按值捕获,y按引用捕获
3)、[&] //用到的任何外部变量都隐式按引用捕获
4)、[=] //用到的任何外部变量都隐式按值捕获
5)、[&,x] //x显式按值捕获,其他变量按照引用捕获
6)、[=,&z] //z按引用捕获,其他变量按值捕获
parameters:存储函数的参数,当parameters为空的时候,()可以省去
return-type:函数的返回值,如果funtion body中存在return语句,则该lambda表达式的返回类型由return语句的返回类型确定。
body:函数体
例子:
auto fun=[](int x){ return x; }
cout<<fun(1)<<endl; //输出1
四、仿函数
本质:仿函数的本质就是类重载了一个operator(),创建一个行为类似函数的对象。
例子:
template<class T>
stuct plus:public binary_function<T,T,T>{
T operator()(const T &x,const T &y) const{return x-y;}
};
cout<<"plus="<<plus<int>(2,1)<<endl; //输出1
五、std::function与std::bind本质
1、std::finction
std::function是函数模板类(是一个类);std::bind是函数模板(是一个函数),其包含在#include<functional>文件中。
std::function 即把函数对象化,将函数当作一个类的对象,主要目的是期望看到更多的泛型算法,不希望看到使用函数取操作数据的代码
通过std::function对C++中各种可调用实体(普通函数、lambda表达式,函数指针、以及其他的函数对象等)的封装,形成一个新的可调用的std::function对象,让我们不再纠结那么的的可调用实体。
例子:
1)、std::function<int(int a)> func //声明一个std::function对象
2)、int test(int){return a}; //普通函数
3)、auto test=[](int a)->int{return a} //匿名函数
4)、class test{ //仿函数
public:
int operator()(int a){
return a;
}
};
5)、class test{ //类成员函数&类静态函数
public:
int tseta(int a){return a}
static int testb(int a){return a;}
};
//调用
//1、普通函数
func=test;
func(1);
//2、匿名函数
func=test
func(1);
//3、仿函数
test t;
func=t;
func(1);
//4、类成员函数
test t;
func=std::bind(&test::testa, t ,std::placeholder::_1); //std::placeholder::_1 :占位符号
func(1);
//5、类静态成员函数
func=test::testb;
func(1);
2、std::bind
std::bind可以看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应原对象的参数列表。
作用:
1)std::bind将可调用对象和其参数绑定成一个仿函数
2)只绑定部分参数,减少可调用对象传入的参数
例子:
//1、绑定普通函数
int test_a(int x,inty){return x+y;}
auto test_A=std::bind(test_a,_1,10); //_1:占位符
test_A(2); //12
//2、绑定类成员函数
struct test_struct{
int test_b(int x,int y){
return x+y;
}
};
test_struct test_tt;
auto test_B=std::bind(&test_struct::test_b,&test_tt,20,30); //第一个参数为类成员函数的指针(必须显示指定函数,编译器不帮忙),第二个参数为类对象的地址(指明哪个对象的指针),后面两个为函数test_b的两个参数
test_B(); //50
c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind的更多相关文章
- day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...
- JS函数 -- 功能,语法,返回值,匿名函数,自调用匿名函数,全局变量与局部变量,arguments的使用
“JavaScript设计得最出色的就是它的函数的实现.” -- <JavaScript语言精粹> 函数包含一组语句,它们是JS的基础模块单元,用于指定对象的行为.一般来说,所谓编程,就是 ...
- 洗礼灵魂,修炼python(24)--自定义函数(5)—匿名函数lambda
在这个互联网时代,大家都喜欢匿名,匿名上网,匿名登录,匿名操作等等,都不喜欢实名对吧?(虽然说现在实名制已经快到来,题外话,扯远了),当然python里也有个不喜欢实名的,它的功效优点特殊,说强大吧? ...
- js闭包(函数内部嵌套一个匿名函数:这个匿名函数可将所在函数的局部变量常驻内存)
js闭包(函数内部嵌套一个匿名函数:这个匿名函数可将所在函数的局部变量常驻内存) 一.总结 1.闭包:就是在一个函数内部嵌套一个匿名函数,这个匿名函数可以访问这个函数的变量. 二.要点 闭包 闭包的相 ...
- php 回调函数结合闭包(匿名函数)的使用示例
<?php /** * php 回调函数结合闭包(匿名函数)的使用 */ function callback( $callback ){ $variable = 'program'; $ret1 ...
- Python:Base4(map,reduce,filter,自定义排序函数(sorted),返回函数,闭包,匿名函数(lambda) )
1.python把函数作为参数: 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x, y, f): return f(x) + f(y) 如果传入abs作为参数 ...
- 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::function和std::bind)
说是延时求值,注意还是想搞一搞std::function和std::bind. 之前博客<C++11新特性之std::function>注意是std::function怎样实现回调函数. ...
- C++11 带来的新特性 (4)—— 匿名函数(Lambdas)
1 语法 Lambdas并不是新概念,在其它语言中已经烂大街了.直接进入主题,先看语法: [ captures ] ( params ) specifiers exception attr -> ...
随机推荐
- Largest Rectangle in a Histogram 杭电1506
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=1506 Problem Description A histogram is a polygon co ...
- Cucumber(1) —— 环境配置
目录 学习资料 cucumber简介 cucumber环境配置 学习资料 1.cucumber官方学习网站 cucumber简介 1.cucumber是一种支持BBD(behavior-driven ...
- redis: Hash集合类型(六)
存值:hset myhash name applesnt 取值:hget myhash name 批量存值:hmset myhash name lisi address bj age 12 批量取值: ...
- ubuntu16.04-交叉编译opencv3.4.6
0.前言 在要移植opecv和SeetaFaceEngine-master到ARM板子上运行的所有步骤之前,有几点需要注意的: 查看板子运行的Kernel版本 交叉编译工具链的gcc版本,关键就是工具 ...
- seo 回忆录百度基本概念(一)
前言 我以前的博客自己做的seo,现在拿来和大家一起交流,是白帽哈,黑帽的不敢发,也不敢学[微笑]. 正文 为什么做seo 做seo说到底就是为了排名.为什么需要排名呢?因为现在人比较懒,只会去查看第 ...
- word2sequence 把字符串转换数字编码
地址:http://ai.stanford.edu/~amaas/data/sentiment/,这是一份包含了5万条流行电影的评论数据,其中训练集25000条,测试集25000条. 1.准备数据 d ...
- Python操作三大主流数据库
Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: ...
- 使用openmp进行共享内存编程
预处理指令pragma:在系统中加入预处理器指令一般是用来允许不是基本c语言规范部分的行为.不支持pragma的编译器会忽略pragma指令提示的那些语句,这样就允许使用pragma的程序在不支持它们 ...
- 负载均衡服务之HAProxy基础配置(五)
前文我们聊了下haproxy的修改报文首部的配置.压缩功能以及haproxy基于http协议自定义健康状态检测机制:回顾请参考https://www.cnblogs.com/qiuhom-1874/p ...
- nginx 配置大吞吐量
ng做反向代理服务是如果没有这两行配置吞吐量到8000-10000就上不去. proxy_http_version 1.1; # 后端配置支持HTTP1.1,必须配 proxy_set_header ...