我有一些遗留代码,它使用显式链接列表来保存定期循环的事件列表。而不是定义下一个'在每个事件节点中的指针,我认为矢量会更紧凑&然而,更有效率的转换我认为是直截了当的,让我进入圈内。我将问题减少到1个文件和一个较小的代码子集,它使用条件' #define'编译LL版本或矢量版本。在LL版本编译时,我无法获得 看起来 的STL版本,就像它应该是等效的,以便干净地编译。
这是测试代码:
#define dummy_defs
//#define USE_LL
#ifndef USE_LL
#include <vector>
using std::vector;
#endif
#ifdef dummy_defs
#define QueuedAfterReading 1
typedef union _XEvent { int type; } XEvent;
void XNextEvent(void) {}
int XEventsQueued(void) {}
#endif
class XWin;
typedef void (XWin::*EventCallBack) (XEvent &event);
class XWin {
static XWin * xparent;
protected:
class Event {
EventCallBack callBack_{};
int event_{};
#ifdef USE_LL
Event * next{};
#endif
public:
friend XWin;
Event(int event, EventCallBack callBack);
virtual ~Event(void){}
void callBack(XEvent &x_event) {
if (x_event.type == event_) (xparent->*callBack_)(x_event);
}
};
#ifdef USE_LL
Event * events_{};
#else
vector<Event *> events_{};
#endif
inline void add_event(int event, EventCallBack callBack) {
#ifdef USE_LL
Event * tmp;
if (events_ == nullptr) events_ = new Event(event, callBack);
else {
tmp=events_;
while (tmp->next) tmp=tmp->next;
tmp->next=new Event(event, callBack);
}
#else
events_.emplace_back(new Event(event, callBack));
#endif
}
void checkevent(void);
};
XWin * XWin::xparent=nullptr;
void XWin::checkevent(void) {
XEvent x_event;
while (XEventsQueued()) {
XNextEvent();
#ifdef USE_LL
for (Event * tmp=events_; tmp; tmp=tmp->next)
tmp->callBack(x_event);
#else
for (Event * tmp:events_) (tmp->callBack)(x_event);
#endif
}
}
上面(在C ++ 11中)给出了错误:
test.cc: In member function ‘void XWin::checkevent()’:
test.cc:79:53: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘tmp->XWin::Event::callBack_ (...)’, e.g. ‘(... ->* tmp->XWin::Event::callBack_) (...)’
for (Event * tmp:events_) (tmp->callBack_)(x_event);
^
如果我尝试按照错误&#34;&#34;说明&#34;,并添加&#39; *&#39;, 我明白了:
test.cc: In member function ‘void XWin::checkevent()’:
test.cc:79:36: error: ‘callBack_’ was not declared in this scope
for (Event * tmp:events_) (tmp->*callBack)(x_event);
^~~~~~~~~
即。 - 另一个错误。第一种形式&#34; tmp-&gt; callBack _&#34;似乎与USE_LL案件相似并且考虑到了&#39; tmp&#39;声明属于&#39;事件*&#39;,我认为访问&#39;事件&#39;中的成员将具有相同的形式,但编译器不会抱怨
程序创建一个在创建后未被修改的事件列表,因此通过STL向量的基本&#39; -type容器似乎是最有效的实现。有人可以指出为什么这两个实现不等同,以及我应该如何制作它们(没有&#39;治愈比原来更糟糕)?
谢谢, -Astara
P.S。修复了矢量大小写以调用代理函数&#39;回调&#39; (有 打回来_)。我试过了,但在某个地方它被修改了。我给出了这个错误:
test.cc: In member function ‘void XWin::checkevent()’:
test.cc:79:36: error: ‘callBack’ was not declared in this scope
for (Event * tmp:events_) (tmp->*callBack)(x_event);
^~~~~~~~
答案 0 :(得分:0)
为了清楚起见,@ user4581301的评论有助于解决原因设计过度使用类似拼写的名称(例如event v.vent_&amp;)所引起的语义问题。具有一些拼写的事件被用于多种类型。当我去校对时,多种变化使得很难看到错误,而且用户4581301指出这些足以让我解决问题。这种混淆是我试图“重构”代码的一个原因。如果有人想看到更正的版本,我会在这里发布。
#define dummy_defs
/*
* The above question demonstrated the original code's use
* of a linked-list that one could 'test' by defining 'USE_LL'.
* The C++ STL implementation uses vector. For clarity, I'll
* leave out the old LL code.
*/
#include <vector>
using std::vector;
// dummy defs to satisfy dependencies similarly to original code
#ifdef dummy_defs
typedef union _XEvent { int type; } XEvent;
void XNextEvent(void) {}
int XEventsQueued(void) {}
#endif
class XWin;
typedef void (XWin::*EventCallBack) (XEvent &event);
class XWin {
static XWin * xparent;
protected:
class Event {
EventCallBack callBack_{};
int event_{};
public:
friend XWin;
Event(int event, EventCallBack callBack);
virtual ~Event(void){}
void callBack(XEvent &x_event) {
if (x_event.type == event_) (xparent->*callBack_)(x_event);
}
};
vector<Event *> events_{};
inline void add_event(int event, EventCallBack callBack) {
events_.emplace_back(new Event(event, callBack));
}
void checkevent(void);
};
XWin * XWin::xparent=nullptr;
void XWin::checkevent(void) {
XEvent x_event;
while (XEventsQueued()) {
XNextEvent();
for (auto tmp:events_) tmp->callBack(x_event);
}
}
答案 1 :(得分:-2)
Your code commented by me:
#define dummy_defs
//#define USE_LL
#ifndef USE_LL
#include <vector> //object library type (might or not be an issue)
using std::vector; // 'std' means 'provided' here
#endif
#ifdef dummy_defs
#define QueuedAfterReading 1
//your type definition
typedef union _XEvent {
int type;
}
XEvent;
void XNextEvent(void) {
}
int XEventsQueued(void) {
}
#endif
class XWin;
//'asterisk' means you are using an 'address' for the value, not the value itself
typedef void (XWin::*EventCallBack) (XEvent &event);
//Your XWin class
class XWin {
static XWin * xparent;//'asterisk' means you are using an 'address' for the parent's value, not the value itself
protected: //scope for the class below
class Event {
EventCallBack callBack_{
};
int event_{};
#ifdef USE_LL
Event * next{};//address of next() node, not the node itself
#endif
public: //scope for the block below
friend XWin;
Event(int event, EventCallBack callBack);//this function arguments are not the same as above, the underscore makes a difference
virtual ~Event(void){}
void callBack(XEvent &x_event) {
if (x_event.type == event_) (xparent->*callBack_)(x_event);
}
};
#ifdef USE_LL
Event * events_{};
#else
vector<Event *> events_{};
#endif
inline void add_event(int event, EventCallBack callBack) {
#ifdef USE_LL
Event * tmp;
if (events_ == nullptr) events_ = new Event(event, callBack);
else {
tmp=events_;
while (tmp->next) tmp=tmp->next;
tmp->next=new Event(event, callBack);
}
#else
events_.emplace_back(new Event(event, callBack));
#endif
}
void checkevent(void);
};
XWin * XWin::xparent=nullptr;
void XWin::checkevent(void) {
XEvent x_event;
while (XEventsQueued()) {
XNextEvent();
#ifdef USE_LL
for (Event * tmp=events_; tmp; tmp=tmp->next)
tmp->callBack(x_event);
#else
for (Event * tmp:events_) (tmp->callBack)(x_event);
#endif
}
}
//Block with 'public:' scope and the related function into the class 'Event' whose scope is 'protected:' <--- , declared above
(I think the PROBLEM IS HERE, check it and tell me).
public: // <--- scope for the block below
friend XWin;
Event(int event, EventCallBack callBack);//this function arguments are not the same as above, the underscore makes a difference
virtual ~Event(void){}
void callBack(XEvent &x_event) {
if (x_event.type == event_) (xparent->*callBack_)(x_event);
}
};
The compiler error message before dereferencing:
test.cc:79:53: error: must use ‘.*’ or ‘->*’ <--- dereference needed ---> :) to call pointer-to-member function in ‘tmp->XWin::Event::callBack_ (...)’, e.g. ‘(... ->* tmp->XWin::Event::callBack_) (...)’
for (Event * tmp:events_) (tmp->callBack_)(x_event);
The compiler error message after dereferencing:
test.cc: In member function ‘void XWin::checkevent()’:
test.cc:79:36: error: ‘callBack_’ was not declared in this scope <--- 'scope' ---> :)
for (Event * tmp:events_) (tmp->*callBack)(x_event);