c++crtptype-deductionc++23explicit-object-parameter

P0847 deducing this - can it allow a generic clone without a need for CRTP?


P0847 proposes the possibility of using explicit this parameter for member functions.

Among other great goodies that this proposal brings, there is also the great new possibility for CRTP without C, R and even T.

A common practice for implementing a generic clone in C++ is based on CRTP, see for example this SO post.

Given that we need clone to be virtual (or at least, behave as virtual), to allow:

Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type

And given that the proposal is that a member function with an explicit this parameter shall not be declared virtual.

Would there still be a way to use P0847 in order to implement a generic clone with dynamic behavior and without CRTP?


Solution

  • template deduction only uses static type, whereas Clone need dynamic type, and so virtual.

    P0847 mostly allows to transform

    template <typename T>
    T* Foo(const T& obj);
    // With Obj base of T
    

    into

    template <typename Self>
    Self* Obj::Foo(this const Self& obj);
    

    What you could do though is simplify the covariance with smart pointer.

    struct Clonable
    {
        virtual ~Clonable() = default;
        virtual Clonable* do_clone() const = 0;
    
        template <typename Self>
        std::unique_ptr<Self> clone(this const Self& self)
        {
            std::unique_ptr<Self>(self.do_clone());
        }
    };
    
    struct MyClass : Clonable
    {
        MyClass* do_clone() const override { return new MyClass(*this); }
    };
    

    But CRTP seems better as it allows to avoid to rewrite do_clone for each type.

    (future reflection might simplify Clonable)