代码之家  ›  专栏  ›  技术社区  ›  grigy

如何键入指向返回该方法指针的方法的指针?

  •  9
  • grigy  · 技术社区  · 17 年前

    基本上我有以下课程:

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

    如何键入statedef方法?

    5 回复  |  直到 15 年前
        1
  •  14
  •   Jacob Krall    17 年前

    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. 函数自身的“返回状态a

    3. 它可能没有开销:在现代编译器上,代理类,

        2
  •  8
  •   njsf    17 年前

    仅使用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); }  
    
    };    
    
        3
  •  3
  •   Simon Buchan    17 年前

    编辑:njsf证明我错了。但是,您可能会发现静态强制转换更易于维护,因此我将把其余部分留在这里。

    没有“正确”的静态类型 由于完整类型是递归的:

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

    你最好的选择是使用 typedef void (StateMachine::*StateMethod)(); 然后做丑陋的事 state = (StateMethod)(this->*state)();

    boost::function 需要显式返回类型,至少从我的 docs : boost::function0<ReturnType>

        4
  •  2
  •   1800 INFORMATION    17 年前

    我的原则是不要使用原始成员函数指针。我甚至不知道如何使用原始指针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); }
    };
    

    这个问题肯定比第一眼看到的困难得多

        5
  •  0
  •   Assaf Lavie    17 年前

    我永远记不住可怕的C++函数DESECSPEC,所以每当我必须找出描述成员函数的语法时,例如,我只会引发一个故意的编译器错误,通常会为我显示正确的语法。

    因此:

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

    stateA的typedef的语法是什么?不知道。。让我们试着给它分配一些不相关的东西,看看编译器是怎么说的:

    char c = StateMachine::stateA
    

    编译器说:

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