[C/C++]在宏的参数中使用函数指针

typedef是C/C++中用于为现有类型创建更有意义的别名的关键字。对于普通类型来说,类型在左,别名在右。

typedef int size;

如果函数指针的定义也符合这种样式,那么下面下这样定义才是合理的:

   typedef void(*)(int) Type;

但实际上编译器采用的是如下的定义方式(以上的代码编译不过去的):

typedef void(*Ptr)(int);

至于原因,我认为(妄加猜测),void(*)(int)确实是一个函数指针,是一种类型,但是它还没有名字,而typedef的本意是对存在名字的类型给予别名,在这条规则下第一种定义方式显然是违背的。同样的还有对数组的重命名(本来应该是“typedef char[81] Line;”形式的,但由于同样的原因不能这样做):

   typedef char Line[81];

至于是不是编译器在技术实现上前一种比较困难,我就不得而知了。

回到本文档的主题上面来,我发现函数指针的这种命名方式不能用于实现某些宏,比如有一个宏PtrType也用来对类型重命名,其实现如下:


#define PtrType(_T, _Name) typedef _T _Name;

但实践结果却是:


PtrType(void(int), Ptr)   	// 编译不过去

PtrType(void(*)(int), Ptr)   	// 编译不过去PtrType(int, Ptr)         	// 这样可以的

typedef void(*PTR)(int);

PtrType(PTR, Ptr)         	// 这样可以的

那么有没有办法让上面的宏依然生效呢?随着C++的发展,模板的概念被提出来,但是当把函数指针应用到模板的概念时却出现了问题:如果我们认为”void(int)”或者”void(*)(int)“不能表示自身的话,大名鼎鼎的function在使用上就会是另外一种方式。


function<int(int)> a;		// 现在的使用方式

typdef int(*FT)(int);		// 编译器不支持的function<FT> a;

而实际上在应用于模板概念时,后面的这种方式”FT”被认成了”void”。很不可思议?”FT”明明是个指针呢!

我们且不追究这种概念上的不同意是为什么,又造成了多大的难以理解。但是这种方式却也恰恰能够解决我在本文中提出的这个问题。我们可以利用模板的这一个特性定义一个新的类型定义符号:$。


/** * $,定义类型选择器 */template<class _T> struct ${	/**	 * 基本类型	 */	typedef _T Type;

/**	 * 指针类型	 */	typedef _T *Ptr;

/**	 * 引用类型	 */	typedef _T &Ref;};

$的用法如下:


$<void(int)>::Ptr a = Print;a(3);$<int>::Type i = 0;$<int>::Ref r = i;

我们使用这个符号对前面的PtrType进行改写:

#define PtrType(_T, _Name) typedef $<_T >::Ptr _Name;

这样就可以将函数指针用于宏的实现了:


PtrType(void(int), PTR)PTR b = Print;b(5);
时间: 2024-11-13 09:35:36

[C/C++]在宏的参数中使用函数指针的相关文章

1、C语言中的函数指针

一 通常的函数调用 1 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); 2 3 int main(int argc, char* argv[]) 4 { 5 MyFun(10); //这里是调用MyFun(10);函数 6 7 return 0; 8 } 9 10 void MyFun(int x) //这里定义一个MyFun函数 11 { 12 printf("%d\n",x); 13 } 这个MyFun函数是一个无返回值的函数,它

C++中传送函数指针

函数指针是一种非常好的类型.因此,可以编写一个函数,它的一个参数是函数指针.然后,在(外部)函数使用其函数指针参数时,就间接地调用在调用函数时对应参数指向的函数. 由于指针在不同的情况下可以指向不同的函数,因此允许调用程序确定要从外部函数中调用哪个函数. 在用函数指针类型的参数调用函数时,参数可以只包含函数地址的相应类型的指针.还可以把函数名作为参数,显示传送函数.作为参数传送给另一个函数的函数有时称为回调函数. 示例: #include <iostream> using std::cout;

C++中使用函数指针 【瓦特芯笔记】

     在C++类中使用函数指针. 类型定义:      typedef 返回类型(类名::*新类型)(参数表) //类定义 class CA { public: char lcFun(int a) { return; } };      CA ca;      typedef char (CA::*PTRFUN)(int);      PTRFUN pFun;     void main()     {        pFun = CA::lcFun;        ca.(*pFun)(2

C++中的函数指针

时间:2014.06.14 地点:基地 ------------------------------------------------------------------------------- 一.函数指针简介 函数指针指向的是一个函数,而不是一个对象.但函数指针也和其他普通指针一样,指向特定的函数类型,函数的类型由返回类型和形参类型共同决定,与函数名无关,就像和变量名无关一样.比如: bool LengthCompare(const string&,const string& );

结构体中定义函数指针

转自:http://blog.csdn.net/unix21/article/details/9293877 结构体指针变量的定义,定义结构体变量的一般形式如下: 形式1:先定义结构体类型,再定义变量 struct结构体标识符 { 成员变量列表;… }; struct 结构体标识符 *指针变量名; 变量初始化一:struct结构体标识符 变量名={初始化值1,初始化值2,…, 初始化值n }; 形式2:在定义类型的同时定义变量 struct结构体标识符 { 成员变量列表;… } *指针变量名;

C语言结构体中的函数指针

这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in-c-struct.html,转载请注明源地址. 引言 指针是C语言的重要组成部分, 于是深入理解指针并且高效地使用指针可以使程序员写出更加老练的程序.我们要记住指针是一个指向内存地址的变量.指针可以引用如int.char……常见的数据类型,例如: int * intptr; // 声明一个指向整型值的

Delphi中的函数指针判断是否为空

delphi函数指针 只有@@p才代表了函数指针本身的地址   assigned(p) 判断是否为空 或者用 @p=nil 来判断函数指针是不是为空 Delphi中的函数指针实际上就是指针,只是在使用的时候有些不同 函数指针要先定义一个函数类型,比如 type TTestProc = procedure of object; 这是一个最简单的函数类型,没有参数,也没有返回值,并且要求是类的成员函数 类的成员函数其实就代表了调用的时候参数的不同,因为类的成员函数隐含着一个对象参数,而不是显式写明,

QT中使用函数指针

想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*commandFun)(void);一个QString ,一个指向MainWindow类成员函数的指针.但是没想到在类中使用函数指针这么复杂. 一般情况,我们使用函数指针声明和引用都很简单明了.但是在类中就不一样了.最后的成功的形式如下: class command_type { public: comm

C 中typedef 函数指针的使用

类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer;     //整型变量int *pointer;   //整型指针变量int array [5]; //整型数组变量int *p_array [5]; //整型指针的数组的变量int (*array_pointer) [5];//整型数组的指针的变量int function (int param);//函数定义,也可将函数名看作函数的变量int