2015-07-05 218 views
1

我有一個類Alpha和一個函數pointFun,它應該接受Alpha成員函數和通用外部函數(例如:主定義)。C++接受成員函數指針和外部函數指針

我已覆蓋pointFun,使其可通過Alpha成員函數和外部函數使用。但由於pointFun功能其實很長,我想避免重複兩遍。

有沒有辦法接受這兩種函數指針類型?我試圖做到這一點(請參閱代碼的評論部分),但它不起作用。

// fpointer.h 

#include <iostream> 
using std::cout; 
using std::endl; 

class Alpha { 
    public: 
     Alpha() {} 

     void pointFun (void (Alpha::*fun)()); 
     void pointFun (void (*fun)()); 
     //void pointFun (void (*funA)(), void (Alpha::*funB)()); // <-- how to make THIS instead of the previous two? 
     void printA (); 
     void assignF (); 

    private: 
     int value; 
     bool set; 
}; 

void Alpha::pointFun(void (Alpha::*fun)()) { 
    (Alpha().*fun)(); 
} 

void Alpha::pointFun(void (*fun)()) { 
    (*fun)(); 
} 

/* // I want this: 
void Alpha::pointFun(void (*funA)() = 0, void (Alpha::*funB)() = 0) { 
    (*funA)(); 
    (Alpha().*funB)(); 
    // same code, different pointer functions 
} 
*/ 

void Alpha::printA() { 
    cout << "A" << endl; 
    // some long code 
} 

void Alpha::assignF() { 
    pointFun(&Alpha::printA); 
} 

這是主要的:

// MAIN.cpp 

#include <iostream> 
#include "fpointer.h" 
using namespace std; 

void printB() { 
    cout << "B" << endl; 
    // same long code as before 
} 

int main() { 
    Alpha A; 
    A.pointFun(printB); 
    A.assignF(); 
} 
+1

成員ve的實現rsion看起來非常可疑和愚蠢。 –

+0

那麼你將如何實現它? (我是新的函數指針) – AndroidGuy

+1

@AndroidGuy應該可以使用正確定義的['std :: function <>'](http://en.cppreference.com/w/cpp/utility/functional/function )模板作爲參數。 –

回答

1

您可以創建,這需要std::function的方法,並期待它爲你的特殊情況:

class Alpha { 
public: 
    void pointFun (std::function<void()> f); // Long function definition 

    void pointFun (void (Alpha::*fun)()) { pointFun([this, fun](){(this->*fun)();}); } 

// Other stuff 
}; 
+0

那太棒了!但對我來說不起作用:它表示'錯誤''沒有被捕獲'。如何解決這個問題? (這是指代碼的這一部分:'(this - > * fun)') – AndroidGuy

+1

@AndroidGuy:對不起,忘記捕獲'fun'。現在修復。 – Jarod42

+0

謝謝,現在這是完美的:D – AndroidGuy

1

肯定的:

struct Foo 
{ 
    using Fn = R(T1, T2, T3); 

    R execute(Fn * f, T1 a1, T2 a2, T3 a3) 
    //  ^^^^^^ 
    //  free pointer 
    { 
     return f(a1, a2, a3); 
    } 

    R execute(Fn Foo:: *f, T1 a1, T2 a2, T3 a3) 
    //  ^^^^^^^^^^^ 
    //  pointer-to-member 
    { 
     return (this->*f)(a1, a2, a3); 
    } 

    // e.g. 
    R you_can_call_me(T1, T2, T3); 
}; 

R i_am_free(T1, T2, T3); 

R dispatch(bool b, Foo & x, T1 a1, T2 a2, T3 a3) 
{ 
    if (b) { x.execute(&i_am_free, a1, a2, a3); } 
    else { x.execute(&Foo::you_can_call_me, a1, a2, a3); } 
}