具有函数指针的C ++运算符优先级

时间:2018-10-05 04:39:11

标签: c++ operator-precedence

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

所以

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

是函数调用和工作代码。 (它可能是一个函数指针)

请您用下一个表达式的运算符优先级来形容我吗?

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

iter->句柄和..下一个?我不能遵循代码。

(我想要这样的描述,https://stackoverflow.com/a/27283893/3818785

4 个答案:

答案 0 :(得分:0)

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

很清晰,比链接的问题更清晰。 iter一对一地访问成员。

如果您对handle->*(iter)感到困惑... ->->*几乎相同,除了->接受成员名而->*接受指针。

如果您对括号感到困惑,因为运算符->*的优先级大于->*

答案 1 :(得分:0)

我从cppreference.com上回想起C++ Operator Precedence

  • operator->的优先级为2(更高)
  • operator->*的优先级为4(低)。

两者都是从左到右的(尽管恕我直言,这在这里不起作用)。

这意味着,在

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

operator->首先解决,之后operator->*

即上面的表达式等于

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

请注意,标识符iter有点误导。 iter不是迭代器(并且iterator对于容器和数组具有非常不同的含义)。 相反,auto&中的for (auto&提供了对当前元素的引用(针对:之后的容器中的每个元素)。 (可能是,我有点发– –对不起。)

我有点担心搜寻表达式中iter的重复出现。因此,我尝试完成OP的示例代码以使其成为MCVE

// The following things have been added to make this an MVCE

#include <string>
#include <vector>

using namespace std;

struct CrChkTime {
  CrChkTime(int) { }
  CrChkTime& operator=(int) { return *this; }
  CrChkTime& operator+=(const CrChkTime&) { return *this; }
};

// sample code of OP:

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 */
    // Excluded: ftOnEvent function;
    /** For c++ handlers */
    ftOnEventClass functionClass;
    /** Handle */
    EventListener* handle;

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

int main()
{
    vector<vector<EventNode *>> m_vEventHandlerList;

    int kind = 0, param1 = 0; void *param2 = nullptr; bool ret; // Missing.

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

尽管如此,我仍然不太了解它(我实在太耐心了,无法对此加以说明)–编译器看起来是这样。编译时不会抱怨:

Live Demo on coliru

答案 2 :(得分:0)

这是正在发生的事情(我将其简化为一个可行的示例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);
        }
    }
}

根据operator precedence成员访问规则->优先于指向成员*->的指针,因此顺序如下:

  • A。 iter->handle获取句柄指针EventListener*
  • B。 iter->functionClass获取成员函数指针 ftOnEventClass
  • C。 (A*->B)(123)使用参数调用成员函数

答案 3 :(得分:0)

由于运算符->的优先级高于->*(请参见https://en.cppreference.com/w/cpp/language/operator_precedence),因此以下分析成立:

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

等效于:

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

iter->handle的类型为EventListener*

iter->functionClass的类型为ftOnEventClass

因此,整个表达式是使用iter->handle所指向的对象的指针到成员函数的取消引用。

问题是,我没有在EventListener中看到具有参数列表的成员函数:

(int, int, void*, bool&)

所以我看不到iter->functionClass可能指向什么。