私はテンプレート、訪問者パターン、およびCRTPの助けを借りてメッセージングシステムを作成しようとしています。私はこれらのコンセプトを理解していますが、私は "失われた"タイプを取り戻さなければならない状況にあります。私はBase
クラスを持っていて、Derived<T>
を探しています。それは(たとえそれが1つのタイプと考えられていても)T
が何でもよいと推測する "2つの"タイプのものです(Derived
)。訪問者パターンのクラステンプレートのタイプを取得する
私は2番目のビジターパターンを使用しようとしましたが、これは重く狂っているようですが、実際の解決策は見つかりませんでした。たとえそれがゲーム関連であっても、それはまるで一例であり、私が想定している他のプログラムにも適用できます。私はそれを別のコンテキストで公開することはできません。ここで
は、私は(不必要な例で)使用されるネーミングです:
SubscriberBase
は、(ネットワーククライアントのような)メッセージを送信し、受信したクラスですBroadcaster
は、加入者間のブリッジである(ネットワークのようにスイッチ/サーバ)であり、ベクトルはSubscriberBase
です。
私は、この最小限のコードを思い付いた:問題はタイプTHE_ACTUAL_SUBSCRIBER_TYPE
ある
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
};
。それはどんな "具体的な"加入者でもあり得る。なし成功を収めて
class SubscriberBase {};
template<typename TSubscriber>
class Subscriber : public SubscriberBase { /* some other visitor pattern ? */ };
class EntityCache : public Subscriber<EntityCache>, /* ... */
:この場合には、それはたとえばEntityCache
またはLogger
、CommandRecorder
のような何か他のもののためになる...
私は別のクラスに結合された別のCRTPを使用しようとしました。
すべてのアイデアが評価され、あなたに感謝:)