Search code examples
c++dispatch

Is there a way to infer the type of an object?


This may be a stupid question, I suspect I know the answer (no) because I seem to be hitting a wall here.

Given I have a collection of objects derived from certain class:

class BaseClass;
class DerivedA: public BaseClass;
class DerivedB: public BaseClass;
class DerivedC: public BaseClass;
std::vector<BaseClass> myCollection;

I want to call a method depending on the types of the specific class:

class Processor {
  void doSomething(DerivedA a, DerivedB b);
  void doSomething(DerivedA a, DerivedC c);
}

The problem is, if I access the individual items on the collection and try to call the 'doSomething' method in the 'Processor', it will not be able do decide which method to use (afaik). So my question is: Is there any way to fetch the items in the collection with the right derived-type?


Solution

  • If you are going to keep the doSomething method as it is, this is what is called multiple dispatch and is NOT currently supported by C++.

    If it were a virtual member function of BaseClass then yes it would be the run of the mill C++ polymorphism on the object it is being invoked on, but it would still NOT automatically infer the type of the arguement.

    To get around this you can do something like what is suggested in the earlier link

    void collideWith(Thing& other) {
         // dynamic_cast to a pointer type returns NULL if the cast fails
         // (dynamic_cast to a reference type would throw an exception on failure)
         if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
             // handle Asteroid-Asteroid collision
         } else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
             // handle Asteroid-Spaceship collision
         } else {
             // default collision handling here
         }
     }
    

    Basically keep casting to various possible Derived classes until one works and call one of the methods appropriately(no special effort since the compiler knows what type you are trying to cast to).

    IMPORTANT: as @WhozCraig points out, your vector needs to hold pointers to avoid Object-Slicing and render this whole question moot.