Question

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

Was it helpful?

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.

OTHER TIPS

I think the downcasting is not very good idea in this case. It seems to be a design problem.

However, you could try to implement something like visitor pattern for these classes. It may solve your problem, but I'm not sure, because there are no use examples of B objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top