C++: Dynamic polymorphism for operators

Viewed 66

Is it possible to have dynamic polymorphism for operators? I have a vector of base-class pointers:

std::vector<Event*> events;

where each event is a different derived class (e.g. StartEvent). All derived classes have their operator<< implemented such that they can be printed to the console.

However, this does't work:

std::for_each(events.cbegin(), events.cend(), [] (const Event *ev) {
    std::cout << *ev << std::endl;
});

I get this error:

error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const Event’)
   std::cout << *ev << std::endl;

I tried this:

class Event {
protected:
  Event() { }

  virtual std::ostream& operator<< (std::ostream &stream);

public:
  const int32_t timestamp;
};

which didn't help. Is it a problem, if operator<< is implemented as a friend in the derived classes?

  friend std::ostream& operator<< (std::ostream &stream, const StartEvent& se) {

    /* do stuff */
  }
1 Answers

The classical solution is to declare an << overload as a friend of the base class, and then use it to invoke the appropriate virtual method:

  std::ostream& operator<< (std::ostream &stream, const Event &e) {
      e.format_output(stream);
      return stream;
  }

Now, simply declare format_output() as an ordinary const virtual method in the Event superclass, and override it in each subclass, to format the instance of the class on the given output stream. Mission accomplished.

Related