2008-10-02 114 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。