我正在尝试使用模板,访问者模式和CRTPs的帮助编写邮件系统。我理解这些概念,但仍然处于这种情况下,我必须回顾一种“迷失”类型。我有一个Base
班,我想找到一个Derived<T>
。这是推断“两种”的类型,即使它被认为是一种类型,任何东西都可以是T
。在访问者模式中检索类模板的类型
我试图利用第二个访客模式,这看起来很沉重而且很疯狂,但我没有找到任何工作解决方案。即使它与游戏有关,它只是一个例子,它可以应用于其他程序,我想,我不能在另一个环境中公开它。
这里是我使用的命名(不必要的示例):
SubscriberBase
是发送和接收消息(像一个网络客户端)Broadcaster
是用户之间的桥(如网络中的类交换机/服务器),并包含一个向量SubscriberBase
。
我想出了这个最小代码:
class SubscriberBase {};
class Broadcaster {
std::vector<SubscriberBase*> subscribers;
public:
template<typename TMessage>
void broadcast(TMessage& message) {
for(auto subscriber : subscribers) {
// <<< Here is my problem <<<
message.accept<THE_ACTUAL_SUBSCRIBER_TYPE>(subscriber);
}
}
void attach(SubscriberBase* subscriber) {
subscribers.push_back(subscriber);
}
};
//Base class for handling messages of any type
template<typename TMessage>
class MessageHandler {
public:
virtual void handleMessage(TMessage& message) {}
};
//Base class for messages
template<typename TMessage>
class Message {
friend class Broadcaster;
private:
//Visitor pattern with CRTP
template<typename TSubscriber>
void accept(TSubscriber* subscriber) {
subscriber->handleMessage(*static_cast<TMessage*>(this));
}
};
//Messages
struct EntityCreated : public Message<EntityCreated> {};
struct EntityDestroyed : public Message<EntityDestroyed> {};
struct BurnAllGummyBears : public Message<BurnAllGummyBears> {};
//Subscribers
class EntityCache : public SubscriberBase,
public MessageHandler<EntityCreated>,
public MessageHandler<EntityDestroyed>,
public MessageHandler<BurnAllGummyBears>
{
public:
void handleMessage(EntityCreated& message) override { /* add to cache */ }
void handleMessage(EntityDestroyed& message) override { /* remove from cache */ }
//does not override BurnAllGummyBears because it's not relevant for EntityCache
};
的问题是类型THE_ACTUAL_SUBSCRIBER_TYPE
。它可以是任何“具体”用户;在这种情况下,将例如EntityCache
或别的像Logger
,CommandRecorder
...
我试图用加上另一个类另一个CRTP:
class SubscriberBase {};
template<typename TSubscriber>
class Subscriber : public SubscriberBase { /* some other visitor pattern ? */ };
class EntityCache : public Subscriber<EntityCache>, /* ... */
没有成功。
所有的想法表示赞赏,谢谢:)