在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. IOS开源项目指标

    https://github.com/edagarli/open-ios-projects/blob/master/README.md 版权声明:本文博主原创文章,博客,未经同意不得转载.

  2. Codeforces 39J Spelling Check hash

    主题链接:点击打开链接 意甲冠军: 特定2弦 选择中删除一个字符串的第一个字母,得2个字符串全然同样 问哪些位置能够选 思路: hash求前缀后缀.然后枚举位置 #include <cstdio ...

  3. C# .NET数据库操作

    C# .NET更智能的数据库操作的封装完整版(重构)   前述: 第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路.那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考.在这两天 ...

  4. 在动态THML语句中调用JS函数传递带空格参数的问题

    刚刚遇到一个问题,调用js函数的参数里带空格,造成调用失败的问题.   部分代码如下: html+="<div><a href=javascript:confirm(&qu ...

  5. UWP 中的各种文件路径(用户、缓存、漫游、安装……)

    原文 UWP 中的各种文件路径(用户.缓存.漫游.安装……) UWP 提供了多种不同文件路径访问方式,对应到不同的文件路径中.可能我们只是简单用 ApplicationData.Current 获取一 ...

  6. Entity Framework加载数据的三种方式。

    MSDN文章Loading Related Entities 有 Eagerly Loading Lazy Loading Explicitly Loading 三种方式. 而看到查询中包含Inclu ...

  7. uva 11892 - ENimEN(推理)

    题目链接:uva 11892 - ENimEN 题目大意:给定n堆石子的个数,两人轮流选择石子堆取石子,直到不能取为失败,附加条件,假设前一次操作,即队手的操作,没有将选中石子堆中的石子取完,那么当前 ...

  8. Notepad++ 的使用(插件)

    为 Notepad++ 安装 NppFTP 插件,查看修改虚拟机上的文本文件 0. 常用快捷键 单行.多行注释 //方式 :ctrl+k 区块注释 / * * /方式 :ctrl+q 取消单行.多行. ...

  9. MFC中获取App,MainFrame,Doc和View类等指针的方法

    From: http://hi.baidu.com/wxnxs/item/156a68f5b3b4ed18e3e3bd03   MFC中获取App,MainFrame,Doc和View类等指针的方法 ...

  10. [转]TensorFlow如何进行时序预测

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库.节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组 ...