Search code examples
c++operator-precedence

C++ Operator Precedence with function pointer


class EventListener
{
public:
  const char* getName() { return name; }
  EventListener();
  EventListener(const string& n);

  void addTime(CrChkTime t) { time += t; }
  void resetTime() { time = 0; }
  CrChkTime getTime() { return time; }

private:
  virtual void dummy() {}

  const char* name;
  CrChkTime time;
};

typedef void (EventListener::*ftOnEventClass)(int kind, int param1, void* param2, bool& ret);

typedef struct _eventNode
  {
    /** For c handlers */
    ftOnEvent function;
    /** For c++ handlers */
    ftOnEventClass functionClass;
    /** Handle */
    EventListener* handle;

    /*...constructors...*/
} EventNode;

vector<vector<EventNode *>> m_vEventHandlerList;
for(auto& iter : m_vEventHandlerList[kind])
{
    if(iter->handle != nullptr)
    {
         (iter->handle->*(iter)->functionClass)(kind, param1, param2, ret);
    }
}

so,

(iter->handle->*(iter)->functionClass)(kind, param1, param2, ret);

is function call and working code. (and it might be a function pointer)

please can you describe me with Operator Precedence of next expression?

(iter->handle->*(iter)->functionClass)

iter->handle and.. next? i cannot follwing the code.

(I want a description like https://stackoverflow.com/a/27283893/3818785 this)


Solution

  • Here is what happening (I simplified it to a workable example https://ideone.com/g8IL8s)

    #include <iostream>
    #include <vector>
    
    
    class EventListener
    {
    public:
        void test(int n)
        {
            std::cout << "n is: " << n << std::endl;
        }
    };
    
    typedef void (EventListener::*ftOnEventClass)(int n);
    
    struct EventNode
    {
        ftOnEventClass functionClass;
        EventListener* handle;
    };
    
    
    int main()
    {
        std::vector<EventNode *> m_vEventHandlerList;
        EventListener el;
        EventNode en = { &EventListener::test, &el};
        m_vEventHandlerList.push_back(&en);
    
        for (auto& iter : m_vEventHandlerList)
        {
            if (iter->handle != nullptr)
            {
                (iter->handle->*iter->functionClass)(123);
            }
        }
    }
    

    According to the rules of operator precedence member access -> has precedence over pointer to member *-> So here is the order:

    • A. iter->handle gets handle pointer EventListener*
    • B. iter->functionClass gets member function pointer ftOnEventClass
    • C. (A*->B)(123) calls member function with the argument