[C/C++]在宏的參數中使用函數指針

typedef是C/C++中用於爲現有類型建立更有意義的別名的關鍵字。對於普通類型來講,類型在左,別名在右。
數組

typedef int size;

若是函數指針的定義也符合這種樣式,那麼下面下這樣定義纔是合理的:函數

   typedef void(*)(int) Type;

但實際上編譯器採用的是以下的定義方式(以上的代碼編譯不過去的):
指針

typedef void(*Ptr)(int);

至於緣由,我認爲(妄加猜想),void(*)(int)確實是一個函數指針,是一種類型,可是它尚未名字,而typedef的本意是對存在名字的類型給予別名,在這條規則下第一種定義方式顯然是違背的。一樣的還有對數組的重命名(原本應該是「typedef char[81] Line;」形式的,但因爲一樣的緣由不能這樣作):code

   typedef char Line[81];

至因而不是編譯器在技術實現上前一種比較困難,我就不得而知了。文檔

回到本文檔的主題上面來,我發現函數指針的這種命名方式不能用於實現某些宏,好比有一個宏PtrType也用來對類型重命名,其實現以下:編譯器

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

但實踐結果倒是:編譯

PtrType(void(int), Ptr)   // 編譯不過去function

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);

相關文章
相關標籤/搜索