Random C++ Thing With CRTP

@profezzorn I think its interesting… not too long ago I was introduced to the CRTP via your menu system, and I find myself now using it (albeit in a much less complicated way) for something quite convenient.

Basically the solution is pulled from this Stackoverflow answer:

template <class BASE>
struct RequireClone {
    virtual BASE *clone() = 0;
};

template <class BASE, class DERIVED>
struct Clonable : BASE {
    virtual BASE *clone() const { 
        return new DERIVED(static_cast<const DERIVED&>(*this));
    }
};

While building ProffieConfig V2’s components system, I find myself using a rather complex hierarchy for managing things, laced with hash lookup maps and shared pointers galore, and I got to the point where I needed to do a proper deep copy. It is now I realize why wxWidgets’ wxObject has that Clone() method that’s required of everything… it didn’t even occur to me prior why they had a Clone method at all and why it was needed.

In case it’s not clear, it ends up being used like this:

struct CONFIG_EXPORT Component : RequireClone<Component> {
    ... fiddly bits, mostly pure virtuals ...
};

struct CONFIG_EXPORT AnActualComponent : Clonable<Component, AnActualComponent> {
     ... implementation specification and other things ...
};

Anyways, thought it was interesting because of the timing. And now I’ve learned (in an application I can understand better :sweat_smile:) a use-case for CRTP and a neat little bit of knowledge about a particular implementation detail via firsthand experience. :slight_smile:

EDIT: I also setup Cloneable to have a forwarding ctor for the base type to be used in the ctor for the derived, if applicable.