C++ 將指針細分為:數據指針、數據成員指針、函數指針、成員函數指針。
不可隨意轉換,甚至 void* 也無法轉換為成員指針。
大小不一:32 位系統下 4/8/12/16 字節,視類繼承/虛函數複雜度而定。
Windows SetTimer、_beginthread 僅接受普通/靜態函數指針。
通用變通:靜態函數 + void* 傳遞 this 指針轉調:
class MyThread {
static void StaticEntry(void* pThis) { static_cast(pThis)->Run(); }
void Run() { /* ... */ }
};
_beginthread(&MyThread::StaticEntry, 0, this);
缺點:reinterpret_cast、void* 破壞類型安全,非純正 C++ 風格。
struct A { void doit() { std::cout << val; } int val; };
std::vector v = {A(1), A(2), A(3)};
// 1. 直接傳遞 &A::doit → 編譯錯誤:for_each 需一元可調用物,非成員函數指針
// 2. 靜態轉調函數 → 可行但醜陋
// 3. std::mem_fun_ref(&A::doit) → 正確,但僅限 0/1 參數,語法冗長
std::for_each(v.begin(), v.end(), std::mem_fun_ref(&A::doit));
mem_fun / mem_fun_ref:僅支持 0 或 1 參數的成員函數。std::mem_fun_ref<void, A>(&A::doit)。boost::function 以模板偏特化實現最多 50 參數,但代碼膨脹嚴重。
C++11 可變參數模板 (template) 使單一 std::function 支持任意參數,徹底解決適配難題。
C++Builder 曾擴展 __closure 關鍵字使成員函數指針如普通函數指針般易用,期待標準化吸收類似特性。