如果我有这些声明和定义:
enum Events
{
INIT,
RENDER
};
struct EventBase
{
typedef void (EventBase::*event_callback_type)();
~EventBase() {}
virtual void init() { assert(0); }
virtual void render() { assert(0); }
};
template <enum Events>
struct EventTraits
{
static EventBase::event_callback_type const event_callback;
};
// in a .cpp file
template <>
EventBase::event_callback_type const
EventTraits<INIT>::event_callback(
&EventBase::init);
template <>
EventBase::event_callback_type const
EventTraits<RENDER>::event_callback(
&EventBase::render);
// in another class *i are pointers to objects that inherit EventBase
template <enum Events event>
inline void EventNotifier::notify()
{
for (events_type::const_iterator i(event_handlers[event].begin());
i != event_handlers[event].begin() + num_event_handlers[event];
++i)
{
((*i)->*EventTraits<event>::event_callback)();
if ((*i)->num_event_handlers[event])
{
(*i)->notify<event>();
}
// else do nothing
}
}
比方说,事件渲染需要尽可能快的处理,你认为是否值得进行成员模板专门化:
template <>
inline void EventNotifier::notify<RENDER>()
{
for (events_type::const_iterator i(event_handlers[RENDER].begin());
i != event_handlers[RENDER].begin() + num_event_handlers[RENDER];
++i)
{
(*i)->render();
if ((*i)->num_event_handlers[RENDER])
{
(*i)->notify<RENDER>();
}
// else do nothing
}
}
这将不需要获取指向成员函数的静态指针。或者我应该这样做:
template <enum Events>
struct EventTraits
{
static EventBase::event_callback_type event_callback();
};
并专门化结构模板?
发布于 2012-05-22 18:27:44
只需再加5美分。notify()看起来完全是线程不安全的。此外,如果任何事件处理程序生成新的事件,则可能会发生不好的事情。我建议这样做通知(C++ 11,只是不知道你的所有类型):
template <> inline void EventNotifier::notify<RENDER>()
{
decltype(event_handlers[RENDER]) local;
decltype(num_event_handlers[RENDER]) local_num;
{
std::lock_guard<std::mutex> guard(my_mutex);
local = event_handlers[RENDER];
local_num = num_event_handlers[RENDER];
}
for (events_type::const_iterator i(local.begin()); i != local.begin() + local_num; ++i)
{
(*i)->render();
if ((*i)->num_event_handlers[RENDER]) (*i)->notify<RENDER>();
}
}
发布于 2012-05-22 18:51:18
成员专门化不会对其当前形式产生任何影响,因为您编写的代码与编译器将为您生成的代码完全相同。
这里有一个小的改进:
template <enum Events event>
inline void EventNotifier::notify()
{
for (events_type::const_iterator i(event_handlers[event].begin()),
end (event_handlers[event].begin() + num_event_handlers[event]);
i != end; ++i)
{
((*i)->*EventTraits<event>::event_callback)();
if ((*i)->num_event_handlers[event])
{
(*i)->notify<event>();
}
// else do nothing
}
}
https://stackoverflow.com/questions/10699899
复制相似问题