Boost logo

Boost :

From: Sean Parent (sparent_at_[hidden])
Date: 2001-11-05 18:11:17


Sorry if this has wandered off enough that it should be moved to comp.lang -
Since there doesn't seem to be a good answer I'll move it there for further
discussion.

 
> shared_ptr in shared_ptr_updates.zip has a constructor of the form
>
> template<class D> shared_ptr<T>::shared_ptr<T>(T * p, D d);

This goes full circle to my original question. Asked another way - is there
a way to make it easy to declare a deleter function object (or any function
object) from a pointer to a function that is statically bound to the pointer
so it can have a default constructor? This wasn't intended to be any
criticism or analysis of shared_ptr, it was just pointed out to me to look
at how it is done there - but it isn't done there.

The issue boils down to deriving the type of a value in a class template -

That is, is there any way to create a template that looks something like
this (or could be used as one would imagine this could be):

template <Type Value>
class foo {...};

Where both Type and Value are template parameters. The best I've been able
to do is:

template <typename Type, Type Value>
class foo {...};

But that requires the user of the template to specify the Type, which can be
derived from the Value. To tie this back to the shared pointer example, I
would like to statically bind the delete to a function:

Given:

void MyDelete(TFoo*);

I'd like to be able to write something like:

typedef smart_ptr<TFoo, &MyDelete> SmartFoo;

If I were to do this today - I would have to turn MyDelete() into a function
object with a default constructor:

struct MyDelete_t { void operator () (TFoo* x) { MyDelete(x); } };

Trying to explain when you need to do that, vs. calling ptr_fun, or mem_fun
gets even more interesting. I frequently answer questions like "why doesn't
this work:

std::map<TFoo, int, std::mem_fun(&TFoo::less)> fooMap;"

When, really, this should work (by "should", I mean this provides enough
information to the compiler to generate correct code):

std::map<TFoo, int, &TFoo::less> fooMap;

The answer today is that you have to write this:

std::map<TFoo, int, std::const_mem_fun1_ref_t<bool, TFoo, const TFoo&> >
    fooMap(std::mem_fun(&TFoo::less));

[I'm not even sure I got that one correct!] Or if you really want it
statically bound you would have to give up on the adaptor and write this:

struct TFoo_less_t :
        public std::binary_function<const TFoo&, const TFoo&, bool>
    {
    bool operator() (const TFoo& x, const TFoo& y) { return x.less(y); }
    };

std::map<TFoo, int, TFoo_less_t> fooMap;

The result is that the complexity of use is a barrier to adoption- the
"customers" that I'm targeting are not new developers starting new projects
but rather seasoned developers attempting to incorporate C++ and STL into
very large legacy code bases. They need a library which is both very
adaptive and easy to use.

Sean

on 11/5/01 12:14 PM, Peter Dimov at pdimov_at_[hidden] wrote:

> From: "Sean Parent" <sparent_at_[hidden]>
>> Perhaps I'm wrong - but my read of shared_ptr leads me to believe that if
> I
>> have a special function to delete my pointer then I need to either
>> specialize shared_deleter<> or, I suppose, overload checked_delete<>().
>>
>> Further - if I have an allocator that requires instance data I have no way
>> to provide that to shared_ptr.
>
> shared_ptr in shared_ptr_updates.zip has a constructor of the form
>
> template<class D> shared_ptr<T>::shared_ptr<T>(T * p, D d);
>
> that takes an arbitrary "deleter" function object (except that its copy
> constructor must not throw.)
>
> --
> Peter Dimov
> Multi Media Ltd.
>
>
> Info: http://www.boost.org Unsubscribe:
> <mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>

-- 
Sean Parent
Sr. Computer Scientist II
Advanced Technology Group
Adobe Systems Incorporated
sparent_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk