いくつかのコンテキスト:(私は複雑なデータを処理するモジュールを持っていますが、それのいくつかのセマンティクスを知っていなければなりません。データはパケットと見なすことができます:モジュールは不透明なペイロード文字列についてのみ解釈する必要がありますが、最終的にはより多くの情報を必要とする人にすべてを渡します。しかし、それはいくつかの未知のパケット情報について...「バンドル」のパケットに持っているので、私はこの思い付いた:今多型(純粋抽象)マップキーは型の安全性を犠牲にしますか?
struct PacketInfo {
virtual void operator==(PacketInfo const&) const = 0;
virtual void operator<(PacketInfo const&) const = 0;
virtual ~PacketInfo() {}
};
class Processor {
private:
template <typename T> struct pless {
bool operator()(T const* a, T const* b) const {
assert(a && b);
return *a < *b;
}
};
// this is where the party takes place:
std::map<PacketInfo const*,X,pless<PacketInfo> > packets;
public:
void addPacket(PacketInfo const*,X const&);
};
、アイデアは、ユーザーが自分のPacketInfo
セマンティクスを実装し、渡すこと、であることによって私のクラス。例えば:私はstatic_cast
ほとんどの人がdynamic_cast
を使用しますが、RTTIは、プロジェクト・ポリシーとして非アクティブ化される使用時点で
(応答する前に、慎重に質問の終わりをお読みください)
struct CustomInfo : public PacketInfo {
uint32_t source;
uint32_t dest;
void operator==(PacketInfo const& b) const {
return static_cast<CustomInfo const&>(b).dest == dest
&& static_cast<CustomInfo const&>(b).source == source;
}
// operator< analogous
};
。もちろん私は自分のタイプ情報を醸造することができますが、私は前にこれを行っていますが、それはここでは問題ではありません。
質問:タイプセーフティーを犠牲にすることなく、つまりキャストせずに、自分が望むもの(コンテンツを知らずに地図キーを持つこと)を得るにはどうすればよいですか?私はProcessor
クラスを非テンプレート型にしたいと思っています。
まず、 'PacketInfoChild1'は' PacketInfoChild2'と比較する必要はありません。マップには、常に同じ派生型のキーのみが含まれている必要があります。第二に、 'Processor'は' ConcretePacketInfo'がどのように見えるかを知りません。それは何もしません。 ...私はモジュールの分離にかなり関心があります... – bitmask
@bitmask:基本クラスのすべてのテンプレートプロセッサに共通コードを因数分解するか、またはプロセッサクラスへのベースポインタを提示し、マップを保持するテンプレート媒介オブジェクトを持つことができますプライベートオブジェクトとして。ポイントは、マップが比較が意味をなさない特定の型を処理する必要があることです。 'addPacket'メソッドも固有でなければなりません。 –
しかし私はまだヘッダーに私の 'Processor'ロジックの大部分(ほとんどすべて)を持っています。もちろん、 'Processor'をテンプレート化することで問題は解決しますが、避けたい解決策です。 – bitmask