Some context: (Feel free to skip ahead) I have a module that processes complex data, but only has to know some semantics of it. The data can be considered a packet: The module should only reason about the opaque payload-string, but it will eventually pass the whole thing to a guy who needs more information. However, it has to ... "bundle" packets regarding some unknown packet information, so I came up with this:
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&);
};
Now, the idea is, that the user implements his PacketInfo
semantics and passes that through my class. For instance:
(please read carefully the end of the question before answering)
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
};
At the point where I use a static_cast
most people would use dynamic_cast
but rtti is deactivated as a project-policy. Of course I can home brew my own type information, and I have done this before, but that is not the question here.
The question is: How can I get what I want (i.e. having a map key without knowing its content) without sacrificing type safety, that is, without casting at all? I would very much like to keep the Processor
class a non-template type.