Некоторый контекст: (Не стесняйтесь пропустить вперед) У меня есть модуль, который обрабатывает сложные данные, но должен знать только некоторую его семантику. Данные можно рассматривать как пакет: модуль должен рассуждать только о непрозрачной строке полезной нагрузки, но в конечном итоге он все это передаст человеку, которому нужна дополнительная информация. Однако он должен ... "связывать" пакеты относительно некоторой неизвестной информации о пакете, поэтому я придумал следующее:
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
семантику и передает ее через мой класс. Например:
(пожалуйста, внимательно прочтите конец вопроса, прежде чем отвечать)
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
};
В тот момент, когда я использую static_cast
, большинство людей будут использовать dynamic_cast
, но rtti деактивирован как политика проекта. Конечно, я могу самостоятельно подготовить информацию о типе, и я делал это раньше, но вопрос не в этом.
Возникает вопрос: как я могу получить то, что хочу (т. Е. Иметь ключ карты, не зная его содержимого), не жертвуя безопасностью типов, то есть вообще без приведения? Я бы очень хотел, чтобы класс Processor
не был шаблоном.