0

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

Nava2
  • 437
  • 3
  • 16
  • The design doesn't really make much sense as stated. What exactly are you are trying to accomplish? – SeaBass Aug 04 '13 at 15:17
  • you didn't explain details about `A` and `B`, so I recommend to look to the `boost::variant` -- possible you may find another way to solve your task – zaufi Aug 04 '13 at 15:17
  • If your users know beforehand what type they need, why are you lumping them all in a single container? – n. m. could be an AI Aug 04 '13 at 15:27
  • If you are concerned with the how often the usage of these types require checking the result of a cast you are casting too much. If you are casting too much there is IMHO a problem with your design. Unfortunately you did not provide enough information about what you are trying to accomplish to address that aspect of your goals. I suggest you revisit your design and see if you can expand the contract of the base class to reduce or eliminate the need to cast. – Captain Obvlious Aug 04 '13 at 15:36
  • Originally, this was a better design due to the contract being that there wasn't any dynamic nature to it. There was one of each made, etc.. The design requirements have changed and I think I might need to stop trying to reuse the old versions, and aim for new. – Nava2 Aug 04 '13 at 15:45

2 Answers2

1

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.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

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.

Unforgiven
  • 125
  • 6