generic flyweighting function
The first thing I would note is that you should point out non obvious features of your implementation. The nice thing that is not immediately obvious is that when all external references are gone the object is automatically deleted from the make_one()::values set.

This is not really a requirement of a flyweight.
But a nice little trick here.

So if the automatic deletion is required then the answers to the question are:


  Can I avoid requiring enable_shared_from_this?


No. I don't think so.  

You could re-invent some reference counting model but that seems a lot of work in comparison to simply using the standard libraries.

As an alternative, You can get around it slightly by using std::set&lt;std::weak_ptr&lt;T&gt;&gt; the trouble here is that even though the resource would be cleaned up the actual space for the resource would be maintained after the object is destroyed.

If on the other hand automatic deletion is not required.


  Can I avoid requiring enable_shared_from_this?


Yes. there are simpler ways that this could be written if there is no requirement to delete upon all external references going away. Now if you want it again it will still be there.

template&lt;class T&gt;
T const&amp; make_one(const T&amp; value) {

    static std::set&lt;T&gt; values;

    auto result = values.insert(value);
    return *(result.first);
}



  Can I make it thread safe without too much trouble?


Yes simply add a lock on the make_one()


  Any other ideas for improvement.


You could add the ability to move an object into your make_once() rather than copy it each time. Even better would be to allow the construction of T from its parameters.

// Move an object in your set
template&lt;typename T&gt;
std::shared_ptr&lt;const T&gt; make_one(T&amp;&amp; value)

// Emplace a value in your set
template&lt;typename T, typename... Args&gt;
std::shared_ptr&lt;const T&gt; make_one(Args&amp;&amp;... value)