|
Boost : |
From: Hervé Brönnimann (hervebronnimann_at_[hidden])
Date: 2007-06-05 00:36:11
Emil: Interesting twist. I haven't looked at shared_ptr before, but
you are aware of the Lakos allocator model?
www.open-std.org/jtc1/sc22/ wg21/docs/papers/2005/n1850.pdf
It essentially advocates this approach. The whole STL can be made to
follow that protocol, although in that document it is advocated that
there is a pure abstract base class allocator, and that polymorphic
instances be passed as allocator* (in actuality, pointing to an
instance of a type derived from allocator).
Doug, this seems to me what you are trying to achieve, but without
the Lakos model... I've never actually looked at boost:shared_ptr in
detail to see how it can keep an allocator and use it in the
destructor, but I just did: it works b/c the shared_ptr holds a
pointer to a polymorphic representation, i.e. a base class (not a
template) with a virtual destructor (and other virtual functions that
must know the template arguments), such that the class template
(which knows the allocator and derives from the base representation
class) can release memory when the base representation is destroyed.
Interesting trick, shows the power of OO+templates combined.
In order to destroy your function object with an allocator passed at
construction, seems like you should be using the same trick, which
requires that your function object stores a pointer to a wrapper
which instantiates a class template (allocator being one of the tmpl
args) that derives from a base representation with a virtual
destructor. As best I understand... you can use the same trick by
having a boost::function base manager which has a virtual manage
member function, and dispatch this call to a derived class templated
by the allocator. In that way, the base manager does not know about
the allocator, so function object does not need to know either.
Unfortunately, I can't be interested in implementing it, but if
someone with time on their hands was wondering how it's done, I hope
I helped a tiny bit. In any case, it was interesting to me to (re-)
learn the technique... (I think I had learned it once, but it's
always worthwhile to revisit this kind of stuff).
Btw, the overhead you add by this technique is a virtual function
call for all management-related functions (cloning, destroying, etc.)
including for functions which do not care about allocator (function
pointers, member functions and functors with small buffer
optimization). In fact, I think that this cost may be undesirable at
several levels because it also will prevent a number of optimizations
since polymorphic dispatch cuts the compiler off from compile-time
resolution. So it may be best to provide two function class
templates, one without and one with allocators. In passing, I think
the allocator pure abstract base class (as in the Lakos-allocator
model) is better in this respect: you always have an extra pointer
for storing the allocator passed at construction, but the invocation
is not a template nor a polymorphic call (at least not until you
actually want to deallocate). So it does not prevent the
optimizations. Thanks. I learned something more tonight.
On Jun 4, 2007, at 11:24 PM, Douglas Gregor wrote:
>
> On Jun 4, 2007, at 10:57 PM, Emil Dotchevski wrote:
>> One important advantage of using boost::function is that it acts
>> like a
>> function pointer, reducing physical coupling between compilation
>> units. This
>> is very much like shared_ptr.
>>
>> A nice feature of shared_ptr is that it has a single template
>> parameter, T,
>> even though diferent instances of shared_ptr<T> can use different
>> allocators.
>>
>> When using boost::function, one can also provide an allocator, but
>> unlike
>> shared_ptr, the allocator is a default parameter of the
>> boost::function
>> class template.
>
>> Is there a reason why this is necessary? Can't boost::function use
>> similar
>> technique to the one employed by shared_ptr to avoid the need for
>> this
>> second template parameter?
>
> You know, I never even thought about adding it. I didn't know about
> the shared_ptr technique when I put the allocator into
> boost::function, and after the C++ committee removed the allocator I
> didn't think about it any more.
>
> The biggest issue with moving the allocator into the constructor
> (like shared_ptr) is that boost::function doesn't know what type it
> is going to be interacting with... shared_ptr<T> knows it's 'T',
> function does not. However, I think we can work around this issue. It
> certainly would be better to have the allocator supplied in the
> constructor.
>
> I don't know when I would have time to implement this, although I
> would certainly consider adding this functionality to Boost's
> "function". Might you be interested in implementing it?
>
> - Doug
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/
> listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk