在C++ STL的SGI实现版本中,一级空间配置器class __malloc_alloc_template中有一个静态函数的实现如下:

static void (*set_malloc_handler(void (*f)()))() {
void (*old)() = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return (old);
}

没接触过函数指针的人看到这段代码可能会很头疼,不知道这个函数表达什么意思。

其实我们应该由内向外读这段代码的首部:

void (*set_malloc_handler(void (*f)()))()

当我们看到set_malloc_handler有函数调用运算符和参数:(void (*f)()),说明这是个函数,以一个void (*)()类型的函数指针f做为参数(即f是一个函数指针,指向的函数为空参数列表,无返回值),set_malloc_handler前面有一个*,所以这个函数应该返回一个指针,然后指针本身也有空参数列表(),因此该指针指向函数,该函数的返回值也是void,参数列表也为空。

综合起来说,就是我们定义了一个函数set_malloc_handler,它接受一个void (*)()类型的参数f,返回类型为void (*)()。

利用C++11的尾置返回类型表达式函数首部可以写成这样:

auto set_malloc_handler(void (*f)()) -> void (*)()

其中参数类型和返回类型都是void (*)()

其实,我们为了阅读方便,可以改变一下写法,在C++中,我们可以这样写:

typedef void (*PF)(); //我们定义一个函数指针类型PF代表void (*)()类型
static PF set_malloc_handler(PF f) {
PF old = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return (old);
}

这样看起来就比较通俗易懂了。

在C++11新标准中我们也可以把以上typedef类型定义改成using表达式:

using PF = void (*)();

PS:不懂函数指针的可以参考《C++ Primer(第五版)》6.7节

STL函数static void (* set_malloc_handler(void (*f)()))()与函数指针解析的更多相关文章

  1. python之函数名称空间,作用域,嵌套函数

    目录 嵌套函数 定义 名称空间的三大类(只存变量名) 名称空间加载顺序 变量名的查找顺序为 作用域 嵌套函数 定义 函数内部定义的函数,无法在函数外部使用内部定义的函数. def f1(): def ...

  2. 简述static关键字、void与void *(void指针)、函数指针

    static关键字1.修饰局部变量,延长局部变量的生命周期.使变量成为静态局部变量,在编译时就为变量分配内存,直到程序退出才释放存储单元.2.修饰全局变量,限制全局变量的使用范围为本文件中.全局变量默 ...

  3. signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析

    转:http://blog.sina.com.cn/s/blog_4850a7880100hnam.html void (*signal(int signo, void (*fun(int))))(i ...

  4. 把C程序的int main(void)改成static int main(void)会怎样呢?

    如题,把C程序中的主函数int main(void)改成static int main(void)会怎么样呢? 比如把 #include <stdio.h> int main(void) ...

  5. c++11 类默认函数的控制:"=default" 和 "=delete"函数 void fun() = default; void fun()=delete;

    转自:lsgxeva #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #includ ...

  6. typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结

    https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...

  7. void * 和 void 在函数返回值中的区别

    一个很容易糊涂的问题. 在函数的返回值中, void 是没有任何返回值, 而 void * 是返回任意类型的值的指针. 还是看代码吧: #include <stdlib.h> #inclu ...

  8. 某些情况下调用函数为什么要在函数名前加“(void)”

    我们知道,在定义函数时,加在函数名前的"void"表示该函数没有返回值.但在调用时,在函数名前加"(void)"的作用又是什么呢? 最明显的一点就是表示程序并不 ...

  9. typdef void(*fun)(void)笔记【函数指针/typdef函数指针】

    1. 函数指针:返回类型(*函数名)(参数表) 2. 使用typdef void(*fun)(void) typedef的功能是定义新的类型.第一句就是定义了一个MyFun的类型,并定义这种类型为 指 ...

随机推荐

  1. 【Struts2学习笔记(4)】指定需要Struts 2请求后缀的常量定义复杂的过程

    一.指定需要Struts 2请求后缀处理 我们是在违约前.action后缀访问Action. 事实上默认后缀是通过不断"struts.action.extension"进行更改.例 ...

  2. EasyUI入门:怎样引入及简单使用

    或许,仅仅有当做比較大的项目的时候,才会发现封装好的东西会为程序员们带来多少方便.合作开发的时候更应该强调复用,才干更加发挥团队的优势. 今天使用了一些EasyUI,发现非常wonderful! 比方 ...

  3. 智能手环体验:UP24

    背景 穿戴式设备承载了物联网.大数据.健康.智能等各路当下或曾经的热门词汇,其风言风语已经飘荡了两年了.当前市面上比较流行的有国外的 jawbone up 手环.NIKE 的 fuelband 和 f ...

  4. 将git文件挂到cdn上

    网址:http://raw.githack.com/

  5. Android二维码功能实现

    最近二维码真是越来越火了,随便电视上.网络上.商场里,到处都是二维码.而内嵌二维码扫描功能的软件也越来越多,QQ.微信.UC浏览器等等应用都可以对着二维码扫一扫,感觉我们自己的应用里不加上二维码扫描功 ...

  6. node lesson2

    var express = require('express'); var utility = require('utility'); var app = express(); app.get('/' ...

  7. Redis入门手册

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用r ...

  8. 抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单

    原文:抛砖引玉 [镜像控件] WPF实现毛玻璃控件不要太简单 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Vblegend_2013/articl ...

  9. Windows 10 子系统Linux重启(不重启Win10)

    Using CMD (Administrator) net stop LxssManager net start LxssManager

  10. Methods and Systems for Enhancing Hardware Transactions Using Hardware Transactions in Software Slow-Path

    Hybrid transaction memory systems and accompanying methods. A transaction to be executed is received ...