remove type from function with template return value

c++, c++11

Solution

The way to do this is with CRTP:

class A {
public:
    virtual std::string Serialize();
    virtual void Deserialize(std::string);
    virtual A* Clone() = 0;  
};

template <class T>
class HelperA : public A {

    T* Clone() override
        {
            std::string s = Serialize();
            T* t = new T();
            t->Deserialize(s);
            return t;
        }
};

class B : public HelperA<B> {
public:
    std::string Serialize() { ... }
    void Deserialize(std::string) { ... }
};

These 3 level hierarchies are quite common. Basically, the top class is pure interface, as before (note: you should = 0 the other functions too). The middle class uses the CRTP pattern: it is templated on the derived typed. the idea is that by having static access to the derived type, it can automatically implement things like `Clone`. Then the derived type implements any implementation that cannot be done generically.

Notice that the derived-most type inherits from the CRTP class templated on itself. That's where the name comes from (Curiously Recurring Template Pattern). Of course, since inheritance is transitive B also inherits from A still, as originally, enabling the same sort of things.

Here is a full working example that you can execute: http://coliru.stacked-crooked.com/a/8f2b201a06b5abcc. I kept the code in the answer as similar to the question as possible, but in the coliru example there are a few small but important differences:

- usage of owning pointers instead of raw pointers considered good practice in C++, and because smart pointers are not covariant this affects the signatures

- correct use of = 0 and override, as well as const

- an example of the static downcast which is kind of a signature of CRTP that didn't come up with your example

Problem

I have the following classes: ``` class A { public: virtual std::string Serialize(); virtual void Deserialize(std::string); template <typename T> T* Clone() { std::string s = Serialize(); T* t = new T(); t->Deserialize(s); return t; } }; class B : public A { public: std::string Serialize() { ... } void Deserialize(std::string) { ... } }; ``` Now, if I want to clone B, I do the following: ``` B b1; B* b2 = b1.Clone<B>(); ``` Is there any way to remove the template type without re-implementing `Clone` in each and every derived classes? I want something like this: ``` B b1; B* b2 = b1.Clone(); ```

Original source