【函數指針指向的是函數而非對象。和其他指針一樣,函數指針指向某種特定類型。 函數的類型由它的傳回類型和形參類型共同決定,與函數名無關。
bool lengthCompare(const string &, const string &); // 該函數的類型是bool(cosnt string &, const string &)
bool (*pf)(const string &, const string &); // (未初始化)要想聲明一個可以指向該類型函數的指針,隻需要用指針替換函數名即可
】
【當我們把函數名作為一個值使用時,該函數自動地轉換成指針(函數名作為右值使用時可省略取位址符):
pf = lengthCompare;
pf = &lengthCompare; // 等價指派,取位址符是可選的
我們還能直接使用指向函數的指針調用該函數,無須提前解引用指針( 使用函數指針調用其指向的函數可以省略解引用符):
bool b1 = pf("hello", "goodbye");
bool b2 = (*pf)("hello", "goodbye"); // 可選的解引用符
bool b3 = lengthCompare("hello", "goodbye"); // 這三條語句調用了相同的函數
指向不同類型函數的指針間不存在轉換規則,我們可以為函數指針賦一個nullptr 或者值為0 的整形常量表達式,表示該指針沒有指向任何一個函數。】
【重載函數的指針:
當我們使用重載函數的指針時,上下文必須清晰地界定到底應該選用哪個函數;(比如不允許auto p = &func,如果func是重載函數的話)
編譯器通過指針類型決定選用哪個函數,指針類型必須與重載函數中的某一個精确比對。(故使用指針調用函數時不存在選擇的問題)】
【函數指針形參:
和數組類似,雖然不能定義函數類型的形參,但是形參可以是指向函數的指針。此時,形參看起來是函數類型,實際上當成指針使用。
void useBigger(const string &s1, const string &s2,
bool pf(const string &, const string &)); // 形參清單中的函數實際上是函數指針
void useBigger(const string &s1, const string &s2,
bool (*pf)(const string &, const string &)); // 兩條等價的聲明
】
【傳回指向函數的指針:
傳回類型不會自動轉換成指針,是以形式上不能定義成傳回類型為函數的函數。
auto f1(int) -> int (*)(int *, int); // 使用尾置傳回類型的方式聲明函數
int (*f1(int))(int *, int);
PF f1(int); // 事先把PF 類型聲明為指向函數的指針
】
【可以将auto,decltype,類型别名等方式用于簡化函數指針的聲明,形參中的函數指針,傳回函數指針的函數聲明。
使用decltype 作用于某個函數時,它傳回函數類型而非指針類型。】