Search code examples
c++templatesdowncast

C++ -- Method for Casting between different Templated versions of a class


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. :)


Solution

  • 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.