Yesterday, I received this question from a distinguished C++ expert who served on the ISO C++ committee for many years. The email poses a decades-old question that still has the classic roll-your-own answer in C++ Core Guidelines #C.130, and basically asks whether we’ve made significant progress toward automating this pattern in modern C++ compared to what we had back in the 1990s and 2000s.

Before I present my own answer, I thought I would share just the question and give all of you readers the opportunity to propose your own candidate answers first — kind of retro GotW-style, except that I didn’t write the question myself. Here is the email, unedited except to fix one typo…

In trying to wrap my mind around all the new stuff for C++20, I see that there is one idea that has been around for quite a while but I still don’t see implemented. I’m wondering whether I’m missing something obvious, or whether it’s still not there. Suppose B is a base class and I have a shared_ptr<B> that might point to a B or to any class that might be derived from B . Assuming that B and all of its derived classes are CopyConstructible, I would like to create a new shared_ptr<B> bound to a newly created object that is a copy of the object to which my original shared_ptr points. I cannot write this: shared_ptr<B> b1 = /* whatever */; shared_ptr<B> b2 = make_shared<B>(*b1); //NO because that will bind b2 to a copy of the B part of *b1 . I think I can make this work by putting a member function in B along the following lines: class B { shared_ptr<B> clone() const { return make_shared<B>(*this); } // ... }; and then for each derived class, write something like class D: public B { public: shared_ptr<B> clone() const { return make_shared<D>(*this); // not make_shared<B> } // ... }; and then I can write shared_ptr<B> b1 = /* as before */; shared_ptr<B> b2 = b1->clone(); and b2 will now point to a shared_ptr<B> that is bound to an object with the same dynamic type as *b1 . However, this technique requires me to insert a member function into every class derived from B , with ugly bugs resulting from failure to do so. So my question is whether there some way of accomplishing this automatically that I’ve missed?

So here’s your challenge:

JG Question

1. Describe as many approaches as you can think of that could let us semi- or fully-automate this pattern, over just writing it by hand every time as recommended in C++ Core Guidelines #C.130. What are each approach’s advantages and drawbacks?

Guru Question

2. Show a working Godbolt.org link that shows how class authors can write as close as possible to this code with the minimum possible additional boilerplate code:

class B { }; class C : public B { }; class D : public C { };

and that still permits the class’ users to write exactly the following:

shared_ptr<B> b1 = make_shared<D>(); shared_ptr<B> b2 = b1->clone();

Hints: Feel free to use any/all mechanism that some production or experimental compiler supports (if it’s somewhere on Godbolt, it’s legal to try), including but not limited to:

the very old (e.g., macros),

C++11/14/17 features (e.g., decltype),

draft C++20 features (e.g., concepts),

proposals currently before the committee for future C++ (e.g., detection idiom),

or any combination thereof.