So, I have a single templated class, B
, which inherits from a non-template class A
. Now, this templated version B
, has a set of four valid and known template classes, call them B<uint8_t>, B<uint16_t>, B<uint32_t>, B<uint64_t>
.
Currently, I am storing these in a map, boost::unordered_map<std::string, A>
, and I would like to create some way to cast to the different types. I can easily differentiate based on a A::width()
method which returns 8, 16, 32, or 64 respectively.
I have been racking my brain for a good design but I can't figure out a way to get a better solution than having every use casting themselves.
Here is a minimum working case:
class A {
std::size_t width() const = 0;
};
template <typename value> class B : public A {
std::size_t width() const {
return sizeof(value) * 8;
}
};
Within usage:
boost::unordered_map<std::string, A *> _bmap;
template <class T> T cast_A(A * const a) {
switch (a->width()) {
case 8: return dynamic_cast<B<uint8_t> *>(a);
// removed for brevity
}
The problem with this is that it forces the user to check the runtime type of the A
class after, aka making the cast method absolutely useless.
I welcome any input. :)
You could use, e.g., a templated get()
method which converts to the asked for size via a virtual
method going through the largest supported type. If the conversion would loose bits (checked at run-time) you could produce an error.