
On Mon, Jul 6, 2009 at 2:04 AM, Daniel Hulme<st@istic.org> wrote:
On Sun, Jul 05, 2009 at 07:58:49PM -0500, Zachary Turner wrote:
I was wondering from a design perspective, why was it decided that intrusive_ptr should rely on user-defined free functions intrusive_ptr_add_ref and intrusive_ptr_release to handle the reference counting?
One of the main reasons for intrusive_ptr is to have smart pointers to third-party classes that already have their own refcount. Since you can't add a member to a class you don't control, using member functions to manipulate the refcount would rule out that use. The expectation in this case would be that the user would write these two free functions to just call the appropriate member functions on the third-party class. But why not just allow the intrusive_ptr to accept those free functions as constructor arguments, allowing me to pass different free functions for different instances?
This makes it somewhat inconvenient, for some constant type T, to support having two different instances of intrusive_ptr<T>, each of which use a different reference counting strategy.
If there's a clever way to allow this that I'm missing please advise.
I must admit, I'm not really sure what you are trying to achieve. It sounds like you have some instances of T, and you want some of them to store their reference count in some way, and the rest to have a completely unrelated way of storing their reference count. But if this is the case, it sounds like you actually have two different types, and Scott's solution sounds right; and even so, I don't know what you hope to achieve by that.
That is, in fact, the main problem I see. I don't think reference counting *should* be tied to a particular type. I guess the original set of use cases for intrusive_ptr consisted of exactly 1 use case. Namely, "allow smart pointer wrapping of objects which provide their own reference count". But I guess I'd like to use it for a slightly different purpose: allowing smart pointer wrapping of objects with a customizable reference counting scheme. I guess the name "intrusive_ptr" really makes it sound like it's more the original use case, but there's nothing else that really comes close ot fitting the bill, and intrusive_ptr would serve very nicely if it allowed one to specify the reference counting functions on a per-instance level. Imagine, for example, you wanted single-threaded and multi-threaded versions of a reference counting function. Obviously you'd want to use the single threaded version whenever possible since it avoids the overhead of acquiring / releasing a mutex to udpate the reference count. But occasionally you might really need a multi-threaded ref-counted pointer. In this case you could simply construct it with different ref-counting functions. For that particular example, it even fits into the original intrusive_ptr use case where you're just changing *how* you modify the original object's reference count, instead of changing what you modify. Scott's workaround is ok, but it's definitely not going to scale as it will result in combinatorial growth. Maybe what I'm really after is an implementation of shared_ptr that allows one to provide the shared_count implementation?