On Fri, Oct 4, 2013 at 6:39 AM, Thorsten Ottosen < thorsten.ottosen@dezide.com> wrote:
The deleter thing can probably be handled with a consrtuctor like
template< class D, class Args ... > shared_obj( D, Args args... );
For stuff not allocated via new, it can be probably be handled by another version of make_shared_obj.
You pretty much need a separate sort of make_shared type of constructor for this, as Andrey pointed out, otherwise you have ambiguity. Even if you make the first parameter an explicit tag type when specifying a deleter, it doesn't handle the case where the constructed object can also take that parameter (I.E. a shared pointer to a shared pointer). I'm fine with a named function. There are other problems though, for instance, you are implying here that new is used to allocate the object, which is not always the case. The function that does the construction needs to be able to handle that case as well. Even with that, this doesn't account for the use where the shared_ptr is taking control of an already allocated object. In other words, let's say you get returned a pointer from a function that's a part of an API which does its own dynamic allocation and construction, which isn't uncommon. For instance, a factory function returning a pointer to a base class. In this case, the shared_ptr should not be explicitly calling the constructor at all. Almost all of these cases can be handled by named constructor-like functions in a somewhat elegant manner, with the exception perhaps of the last one (what happens if the factory function can return a null pointer? We're back to the original issue, in that case, only worse because the programmer cannot simply handle that case outside of the constructor). I think ultimately my vote would be to support named functions, but there still needs to be a way to do construction via a direct pointer otherwise we are losing functionality that shared_ptr provides. I'll repeat my basic, underlying stance here for people to agree/disagree with. A non-null shared_ptr should be exactly that. It should have the same or extremely similar interface to a shared_ptr (including things like bool-conversion), just with more strict invariants and preconditions. This makes drop-in replacement and use in generic functions easier to deal with and also avoids sacrificing additional functionality that shared_ptr provides. People shouldn't have to avoid switching to a non-null shared pointer simply because they have no way of constructing it with a pointer that they obtained from a factory. -- -Matt Calabrese