كيفية typedef مؤشر إلى الطريقة التي تقوم بإرجاع مؤشر الطريقة ؟

StackOverflow https://stackoverflow.com/questions/160974

  •  03-07-2019
  •  | 
  •  

سؤال

في الأساس لدي فئة التالية:

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

أساليب stateA() و stateB() ينبغي أن تكون قادرة على العودة مؤشرات stateA() و stateB().كيفية typedef على StateMethod?

هل كانت مفيدة؟

المحلول

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. لها آلية شفافة:يمكنك الحصول على الطبيعية بناء الجملة المتصل/المستخدم ، ومن الطبيعي جملة الدالة الخاصة "عودة stateA;" البيان.

  3. ربما لديه صفر النفقات العامة:في الحديث المجمعين ، فئة وكيل ، مع التخزين و الوظائف مضمنة وتحسين بعيدا إلى لا شيء.

نصائح أخرى

وفقط باستخدام الرموز المميزة ل 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); }  

};    

وتحرير: ثبت njsf لي الخطأ هنا. قد تجد ساكنة الصب أسهل للحفاظ على، ولكن، حتى سأترك بقية هنا.

<الإضراب> ليس هناك 'الصحيح' نوع ثابت منذ نوع الكامل هو العودية:

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

وأفضل رهان هو استخدام typedef void (StateMachine::*StateMethod)(); ثم القيام state = (StateMethod)(this->*state)(); القبيح

وPS: boost::function يتطلب نوع الإرجاع واضح، على الأقل من وجهة نظري قراءة في مستندات : boost::function0<ReturnType>

وفلسفتي هي لا تستخدم الخام مؤشرات دالة عضو. أنا حتى لا أعرف حقا كيف أن تفعل ما تريد باستخدام مؤشر الخام typedef وهو بناء الجملة حتى الرهيبة. أحب استخدام دفعة :: وظيفة.

وهذا هو <الإضراب> تقريبا بالتأكيد خطأ:

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); }
};

وهذه المشكلة هي بالتأكيد أصعب بكثير من أول مرة تراه العين

وأنا لا يمكن أبدا أن تذكر الرهيبة C ++ وظيفة declspec، لذلك كلما لدي لمعرفة بناء الجملة التي تصف وظيفة الأعضاء، على سبيل المثال، أنا فقط حمل خطأ مترجم المتعمد الذي يعرض عادة بناء الجملة الصحيح بالنسبة لي.

وهكذا الممنوحة:

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

ما هو بناء الجملة من أجل typedef وstateA على ذلك؟ أي فكرة .. لذلك دعونا نحاول أن تخصص له شيء لا علاقة لها ونرى ما يقول المترجم:

char c = StateMachine::stateA

ومترجم ويقول:

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

ومن هناك: "منطقي (StateMachine :: *) (دولي)" هو typedef ولدينا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top