Defer pattern for constructors in C++ In some specific scenarios, I want to run code after the constructor for a class has run (namely: access std::enable_shared_from_this::shared_from_this()).

To solve this without introducing an error prone init method for all classes with this behaviour I have built a generic pattern that allows constructors to "defer" lambdas to run after the constructor has run (example in end of snippet):

// If derived from this subclasses may call enable_defer::defer in their
// constructor to run code directly _after_ their constructor has completed
// This is useful when for example the constructor wants to access the weak_ptr
// from std::enable_shared_from_this in the constructor.
// Note naming convention matching std::enable_shared_from_this &amp; underscores to avoid collisions in subclasses
class enable_defer
{
    // Allowed factories
    template &lt;typename T&gt;
    friend std::shared_ptr&lt;T&gt; make_shared_deferrable();

    template &lt;typename T, typename... Args&gt;
    friend std::shared_ptr&lt;T&gt; make_shared_deferrable(Args&amp;&amp;... args);

    // Allowed implementations
    template &lt;typename T&gt;
    friend class __impl__;

private:
    std::vector&lt;std::function&lt;void()&gt;&gt; defered;
    bool constructed = false;

    // Only friend classes may have access to this type
    // this is because we only want friend classes to be able to implement the interface
    class __Tag__ {};

    virtual void __constructed__(__Tag__ = __Tag__()) = 0;

    // Implementation of enable_defer kept private
    // to make sure only friend factories above may
    // construct implementations
    template &lt;typename T&gt;
    class __impl__ : public T
    {
        static_assert(std::is_base_of&lt;enable_defer, T&gt;::value, "Must be enable_defer");

        // Forward base class constructors
        using T::T;

        virtual void __constructed__(__Tag__) override
        {
            constructed = true;
            for (auto fn : defered)
                fn();
        }
    };

protected:

    void defer(std::function&lt;void()&gt; fn)
    {
        // Make sure defer is only called in constructor
        assert(!constructed);
        defered.push_back(fn);
    }
};

// Create std::shared_ptr from enable_defer
template &lt;typename T&gt;
std::shared_ptr&lt;T&gt; make_shared_deferrable()
{
    auto shared(std::shared_ptr&lt;T&gt;(new enable_defer::__impl__&lt;T&gt;()));
    shared-&gt;__constructed__();
    return shared;
}

// Create std::shared_ptr from enable_defer
template &lt;typename T, typename... Args&gt;
std::shared_ptr&lt;T&gt; make_shared_deferrable(Args&amp;&amp;... args)
{
    auto shared(std::shared_ptr&lt;T&gt;(new enable_defer::__impl__&lt;T&gt;(std::forward&lt;Args&gt;(args)...)));
    shared-&gt;__constructed__();
    return shared;
}



class Example : public enable_defer, public std::enable_shared_from_this&lt;Example&gt;
{
public:

    Example()
    {
        defer([this]() {
            shared_from_this(); // Works!
        });
    }

    // Factory
    static std::shared_ptr&lt;Example&gt; create()
    {
        return make_shared_deferrable&lt;Example&gt;();
    }
};


Questions:


Are there better ways to accomplish the enforcements of the implementation class and factories?
General improvements
Bugs?
Naming?
General thoughts on this pattern.
Identifiers with leading underscore(s) followed by a capital letter are reserved for the implementation and should not be used in your own code. It's easiest to just avoid leading underscores.
When using enable_shared_from_this it's important to use a static factory function and make the other constructors private. This prevents calling the Example constructor directly (where calling shared_from_this will be undefined behaviour, since we don't have a shared_ptr).




Do we really need enable_shared_from_this? The whole thing could be more easily written as:

    class Example
    {
    private:

        Example() { }

    public:

        static std::shared_ptr&lt;Example&gt; Create()
        {
            auto example = std::make_shared&lt;Example&gt;();
            example-&gt;do_the_thing();

            return example;
        }
    };


It really depends on what do_the_thing() is...

If we have to register the class somewhere after creation (or consistently perform some action), perhaps that logic doesn't belong in the Example class at all.

struct Example {};

struct Registry
{
    template&lt;class T, class... Args&gt;
    std::shared_ptr&lt;T&gt; CreateAndRegister(Args&amp;&amp;... args)
    {
        auto object = std::make_shared&lt;T&gt;(std::forward&lt;Args&gt;(args)...);
        Register(object);
        return object;
    }
};

auto registry = Registry();
auto e = registry.CreateAndRegister&lt;Example&gt;();


While an object has control over it's own copy / move semantics, it generally shouldn't care who / what owns it.

So the question is: why does Example need to "break the 4th wall" and know that it exists inside a shared_ptr?



Large inheritance hierarchies are out of fashion nowadays (with good reason), but with a general solution, you may need to cope with:

struct ExampleA : enable_defer, enable_shared_from_this&lt;ExampleA&gt; {};
struct ExampleB : ExampleA {}; // what if B wants to defer something?


and

struct ExampleA : enable_defer, enable_shared_from_this&lt;ExampleA&gt; {};
struct ExampleB : enable_defer, enable_shared_from_this&lt;ExampleB&gt; {};
struct ExampleC : ExampleA, ExampleB {}; // uh oh... ?


shared_from_this is quite complicated to use as it is with a class hierarchy.