【发布时间】:2017-03-20 09:29:22
【问题描述】:
我有这门课:
#include <assert.h>
template <typename DeclaringType, typename HandlerType>
using SubscribeMethodType = void (DeclaringType::*)(HandlerType* handler);
template <typename DeclaringType>
using UnsubscribeMethodType = void (DeclaringType::*)();
template <SubscribeMethodType<???_1, ???_2> subscribeMethod, UnsubscribeMethodType<???_1> unsubscribeMethod>
class EventHandler
{
private:
template <typename T>
struct ExtractDeclaringAndHandlerTypes
{
};
template <typename DeclaringType, typename HandlerType>
struct ExtractDeclaringAndHandlerTypes<void (DeclaringType::*)(HandlerType*)>
{
typedef DeclaringType DeclaringType;
typedef HandlerType HandlerType;
};
typedef typename ExtractDeclaringAndHandlerTypes<decltype(subscribeMethod)>::DeclaringType DeclaringType;
typedef typename ExtractDeclaringAndHandlerTypes<decltype(subscribeMethod)>::HandlerType HandlerType;
public:
EventHandler() { }
~EventHandler()
{
Unsubscribe();
}
void Subscribe(DeclaringType* eventOwner, HandlerType* handler)
{
assert(!m_IsSubscribed);
m_EventOwner = eventOwner;
(eventOwner->*subscribeMethod)(handler);
m_IsSubscribed = true;
}
void Unsubscribe()
{
if (m_IsSubscribed)
{
(m_EventOwner->*unsubscribeMethod)();
m_IsSubscribed = false;
}
}
private:
DeclaringType* m_EventOwner;
bool m_IsSubscribed;
};
示例用法:
class IEventConsumer
{
};
class ExampleEventOwner
{
public:
void Subscribe(IEventConsumer* consumer) {}
void Unsubscribe() {}
};
int main()
{
ExampleEventOwner owner;
IEventConsumer consumer;
EventHandler<&ExampleEventOwner::Subscribe, &ExampleEventOwner::Unsubscribe> handler;
handler.Subscribe(&owner, &consumer);
handler.Unsubscribe();
return 0;
}
是否可以指定一些东西而不是“???_1”和“???_2”来允许它们是任何类型?目的是避免此类的使用者必须明确指定 DeclaringType 和 HandlerType,因为它们可以很容易地从 subscribeMethod 和 unsubscribeMethod 推断出来。
注意:我不能使用 C++17。
【问题讨论】:
-
我现在尽可能地简化它。
-
我认为这种模板类型推导是不可能的。
标签: c++ templates c++14 type-alias