2008-10-02 110 views
9

基本上我有以下類:如何typedef指針返回指針方法的方法?

class StateMachine { 
... 
StateMethod stateA(); 
StateMethod stateB(); 
... 
}; 

方法狀態σ()和stateB()應該能夠返回指針狀態σ()和stateB()。 如何typedef StateMethod?

+0

哇,這個問題比我認爲的要難得多。如果你願意打破完整的類型安全性,有各種各樣的方法來解決它,但除此之外......哇。 – 2008-10-02 05:37:45

回答

14

GotW #57說要使用代理類爲此目的進行隱式轉換。

struct StateMethod; 
typedef StateMethod (StateMachine:: *FuncPtr)(); 
struct StateMethod 
{ 
    StateMethod(FuncPtr pp) : p(pp) { } 
    operator FuncPtr() { return p; } 
    FuncPtr p; 
}; 

class StateMachine { 
    StateMethod stateA(); 
    StateMethod stateB(); 
}; 

int main() 
{ 
    StateMachine *fsm = new StateMachine(); 
    FuncPtr a = fsm->stateA(); // natural usage syntax 
    return 0; 
}  

StateMethod StateMachine::stateA 
{ 
    return stateA; // natural return syntax 
} 

StateMethod StateMachine::stateB 
{ 
    return stateB; 
} 

該解決方案有三個主要 優勢:

  1. 要求它解決了這個問題。更好的是,它是類型安全的,並且便攜。

  2. 它的機制是透明的:您可以獲得 調用者/用戶的自然語法,以及 函數自己的「return stateA;」的自然語法。 聲明。

  3. 它可能沒有開銷:在現代編譯器上,具有存儲和函數的代理類 應該內聯並優化爲空。

2

我的理念是不要使用原始成員函數指針。我甚至不知道如何使用原始指針typedef來做你想要的,語法太糟糕了。我喜歡使用boost :: function。

這是 幾乎 肯定是錯誤的:

class X 
{ 
    public: 
    typedef const boost::function0<Method> Method; 

    // some kind of mutually recursive state machine 
    Method stateA() 
    { return boost::bind(&X::stateB, this); } 
    Method stateB() 
    { return boost::bind(&X::stateA, this); } 
}; 

這個問題肯定是很多困難比最初滿足眼睛

+0

嘿,我看到你早先的答案。這可能是最好的折中方案;我正在IRC上討論這個問題,並得出結論認爲指向自身的typedef可能是一個「太難」的問題。 – 2008-10-02 05:29:24

+0

雖然,在內部boost :: function0中,你不必提供返回類型,並再次遞歸? – 2008-10-02 05:30:46

+0

可能,我不是坐在編譯器上 – 2008-10-02 05:32:19

3

編輯:njsf證明我錯了這裏。然而,你可能會發現靜態鑄件更容易維護,所以我會把其餘的放在這裏。

沒有「正確」的靜態類型 因爲完整的類型是遞歸的:

typedef StateMethod (StateMachine::*StateMethod)(); 

最好的辦法是使用typedef void (StateMachine::*StateMethod)();然後做醜state = (StateMethod)(this->*state)();

PS:boost::function需要一個明確的返回類型,至少從我讀的docsboost::function0<ReturnType>

8

只需使用的typedef:

class StateMachine { 

public: 

    class StateMethod;  
    typedef StateMethod (StateMachine::*statemethod)(); 

    class StateMethod { 

    statemethod method; 
    StateMachine& obj; 

    public: 

    StateMethod(statemethod method_, StateMachine *obj_) 
     : method(method_), obj(*obj_) {} 

    StateMethod operator()() { return (obj.*(method))(); } 
    }; 

    StateMethod stateA() { return StateMethod(&StateMachine::stateA, this); } 

    StateMethod stateB() { return StateMethod(&StateMachine::stateB, this); } 

};  
0

我永遠記得可怕的C++函數declspec,所以每當我必須找出一個描述成員函數,例如語法,我只是引發一個故意的編譯器錯誤,通常會爲我顯示正確的語法。

所以給出:

class StateMachine { 
    bool stateA(int someArg); 
}; 

什麼是對狀態σ的類型定義的語法?不知道..所以讓我們嘗試分配給它的東西無關,看看編譯器說:

char c = StateMachine::stateA 

編譯器說:

error: a value of type "bool (StateMachine::*)(int)" cannot be used to initialize 
     an entity of type "char" 

在那裏,它是:「布爾(的StateMachine :: *)( int)「是我們的typedef。