我正在嘗試使用模板,訪問者模式和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>, /* ... */
沒有成功。
所有的想法表示讚賞,謝謝:)