samedi 12 novembre 2016

Adding a comparator to a class hierarchy, safely

I have what seems like a simple and common scenario, and I cannot figure out how to do it.

I have about 100 classes (some abstract, some mixins multiply-inherited) in a class hierarchy. All I want to do is find a simple way to compare objects in this hierarchy so that I can avoid duplicates in vectors of them.

That is, my goal is, to give a function f like vector::unique such that f(vector<Node*>) removes duplicates from its argument.

The problem is that if I write 100 different comparators, then I don't have a way to check that I didn't actually miss a field in one of the comparators.

So how do I do this in C++?

More specifically, the root of the hierarchy is Node. Each subclass C of node has members of the one of the following types:

  1. N*, where N is a subclass of Node;

  2. vector<N*>, where N is a subclass of Node;

  3. A class V with a prexisting V::operator< , where V is not a subclass of Node;

  4. A vector<V> as above

For example, a typical class definition might be:

class N : public Node {
   public:
      vector<N*> children;
      vector<Node*> siblings;
      M* parent; //M is a subclass of Node
      Orientations vector<Orientation> ; // another class, with comparator
    };

I'm also not sure I can use default tuple comparator since that doesn't handle the vector members correctly.

Thus, I want a method, for each N in the class hierarchy, like

 bool N::operator<(const N& o)

that determines whether this < o. Given such a method, I could just use algorithm::sort and algorithm::unique to remove duplicates.

It is easy to say this in words. Just sort each class by its members lexicographically; compare pointers by what they point to; and compare vectors lexicographically.

So it's one sentence to describe and would be trivial in a language with reflection - but how to do it in C++?

Efficiency is irrelevant, I just want it to work without accidentally leaving out a field - now or in the future. I don't have a way to test, you see, if I leave out a field, which is why I don't want to do it manually (also a maintenance nightmare to write 100 different operator< for 100 different classes).

So how do C++ experts handle this kind of issue, which must arise whenever anyone has a class hierarchy whose objects they want to sort?





Aucun commentaire:

Enregistrer un commentaire