Based on ecatmur's answer, we could make the Base construct constructive from a type that has only a private constructor:
class PrivateT { PrivateT() { } template <typename Impl, typename... Args> friend std::shared_ptr<Impl> makeDerived(Args&&... ); }; struct Base : std::enable_shared_from_this<Base> { Base(PrivateT ) { } virtual void foo() = 0; void bar() { baz(shared_from_this()); } }; template <typename Impl, typename... Args> std::shared_ptr<Impl> makeDerived(Args&&... args) { return std::make_shared<Impl>(std::forward<Args>(args)..., PrivateT{}); }
Each type of Derived will have to take an additional argument from a constructor of type PrivateT , which it will have to forward ... but it can still inherit from Base !
struct Impl : Base { Impl(PrivateT pt) : Base(pt) { } void foo() override { std::cout << "Hello!" << std::endl; } }; auto gd = makeDerived<Impl>(); gd->bar();
Barry
source share