class A{
public:
void Func(int){...}
};
要取得Func函數指針,void (A::*pFunc)(int)=&A::Func;
::*是一個特殊操作符,表示pFunc是一個指針,指向A的成員。獲取成員函數的地址不能通過類對象來獲取,必須通過類名獲取,而且要加上取地址操作。
那麼如果通過指針來調用該函數,成員函數都隱含了一個this參數,表示函數要操作的對象,我們只獲取了函數的指針,還缺少一個對象作爲this參數,爲了這個目的,我們先創建一個對象,然後通過該對象來調用成員函數指針:
A a;
( a.*pFunc)(10);
A* pa=&a;
(pa->*pFunc)(11);
對於可變參數模板,一般使用情況是不需要解包的,只需要做一個類似轉發的工作即可
#include <iostream>
#include <string>
using namespace std;
template <class T, class R, typename... Args>
class MyDelegate
{
public:
MyDelegate(T* t, R(T::* f)(Args...)/*需要一個入參爲可變參數的函數指針*/) :m_t(t), m_f(f) {}
R operator()(Args&&... args)
{
return (m_t->*m_f)(std::forward<Args>(args) ...);
}
private:
T* m_t;
R(T::* m_f)(Args...);
};
using pF = void(*)(int, int);
template <class T, class R, typename... Args>
MyDelegate<T, R, Args...> CreateDelegate(T* t, R(T::* f)(Args...))
{
return MyDelegate<T, R, Args...>(t, f);
}
struct A
{
void Fun(int i) { cout << i << endl; }
void Fun1(int i, double j) { cout << i + j << endl; }
};
int main()
{
A a;
auto d = CreateDelegate(&a, &A::Fun); //創建委託 &A::Fun 傳入CreateDelegate相當於 void(A::*f)(int)
d(1); //調用委託,將輸出1
auto d1 = CreateDelegate(&a, &A::Fun1); //創建委託
d1(1, 2.5); //調用委託,將輸出3.5
// my test
void(A:: * pFunc)(int) = &A::Fun;
auto d05 = CreateDelegate(&a, pFunc);
(a.*pFunc)(1);
(&a->*pFunc)(1);
return 0;
}