C++ 运算符优先级与函数指针
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);
}
}
所以,
(iter->handle->*(iter)->functionClass)(kind, param1, param2, ret);
是函数调用和工作代码。
(它可能是一个函数指针)
你能用下一个表达式的运算符优先级来描述我吗?
(iter->handle->*(iter)->functionClass)
iter->handle 和..下一个?我无法遵循代码。
(我想要像 这样的描述)
iter
->
handle
->*
(iter)
->
functionClass
很清楚,比link的问题还清楚。一一访问iter
中的成员。
如果您对 handle->*(iter)
感到困惑... ->
和 ->*
几乎相同,只是 ->
接受成员名称而 ->*
接受成员名称指针。
如果你和括号混淆了,因为运算符->
和*
的优先级大于->*
.
我从 cppreference.com 回忆起 C++ Operator Precedence:
operator->
具有优先级 2(更高)
operator->*
具有优先级 4(较低)。
两者都是从左到右(尽管恕我直言,这在这里不起作用)。
也就是说,在
(iter->handle->*(iter)->functionClass)
operator->
先解决,operator->*
后解决。
即上面的表达式等同于
((iter->handle)->*((iter)->functionClass))
请注意,标识符 iter
有点误导。 iter
不是迭代器(并且 iterator
对于容器和数组具有截然不同的含义)。
相反,for (auto&
中的 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;
}
尽管如此,我仍然没有完全理解它(我太不耐烦了 fiddle 这个)——编译器似乎是这样。它毫无怨言地编译:
事情是这样的(我把它简化成一个可行的例子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 成员访问的规则 ->
优先于指向成员的指针 *->
因此顺序如下:
- 一个。
iter->handle
获取句柄指针 EventListener*
- 乙。
iter->functionClass
获取成员函数指针
ftOnEventClass
- 摄氏度。
(A*->B)(123)
用参数调用成员函数
由于运算符->
的优先级高于->*
(见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
可能指向什么。
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->handle 和..下一个?我无法遵循代码。
(我想要像 这样的描述)
iter
->
handle
->*
(iter)
->
functionClass
很清楚,比link的问题还清楚。一一访问iter
中的成员。
如果您对 handle->*(iter)
感到困惑... ->
和 ->*
几乎相同,只是 ->
接受成员名称而 ->*
接受成员名称指针。
如果你和括号混淆了,因为运算符->
和*
的优先级大于->*
.
我从 cppreference.com 回忆起 C++ Operator Precedence:
operator->
具有优先级 2(更高)operator->*
具有优先级 4(较低)。
两者都是从左到右(尽管恕我直言,这在这里不起作用)。
也就是说,在
(iter->handle->*(iter)->functionClass)
operator->
先解决,operator->*
后解决。
即上面的表达式等同于
((iter->handle)->*((iter)->functionClass))
请注意,标识符 iter
有点误导。 iter
不是迭代器(并且 iterator
对于容器和数组具有截然不同的含义)。
相反,for (auto&
中的 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;
}
尽管如此,我仍然没有完全理解它(我太不耐烦了 fiddle 这个)——编译器似乎是这样。它毫无怨言地编译:
事情是这样的(我把它简化成一个可行的例子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 成员访问的规则 ->
优先于指向成员的指针 *->
因此顺序如下:
- 一个。
iter->handle
获取句柄指针EventListener*
- 乙。
iter->functionClass
获取成员函数指针ftOnEventClass
- 摄氏度。
(A*->B)(123)
用参数调用成员函数
由于运算符->
的优先级高于->*
(见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
可能指向什么。