views:

68

answers:

1
+3  Q: 

bind two arguments

Consider I have the following struct:

struct IDirect3D
{
    IDirect3D() : ref_count_(0) {}
    unsigned long Release() { return --ref_count_; }
private:
    long ref_count_;
    ~IDirect3D() {}
};

I want to use shared_ptr to it like in the followed code (minimal example):

int main()
{
    boost::shared_ptr<IDirect3D> ptr;

    IDirect3D* p = 0; // initialized somewhere
    ptr.reset( p, boost::mem_fn( &IDirect3D::Release ) );

    return 0;
}

This works OK in most cases, but crases if p in equal to 0. I have the following deleter which I want to use:

template<typename T, typename D>
inline void SafeDeleter( T*& p, D d ) 
{ 
    if ( p != NULL ) {
        (p->*d)();
        p = NULL;
    }
}

But the following code gives a lot of error (looks like it dumps the whole bind.hpp):

ptr.reset( p, boost::bind( SafeDeleter, _1, &IDirect3D::Release ) );

What's wrong with my using of bind?

+4  A: 

Release() comes from IUnknown- so why not just use that:

void my_deleter(IUnknown* p) {
    // ...
}

ptr.reset(p, &my_deleter);

Note that Boost also has an intrusive_ptr which would seem more natural here:

void intrusive_ptr_add_ref(IUnknown* p) { p->AddRef (); }
void intrusive_ptr_release(IUnknown* p) { p->Release(); }

boost::intrusive_ptr<IDirect3D> d3d(...);
IDirect3D* p = 0;
d3d.reset(p);

Your actual issue is probably that there is a non-template function SafeDeleter - to specifically use the template-function you'd have to use something like:

ptr.reset(p, boost::bind(&SafeDeleter<IDirect3D, ULONG (IDirect3D::*)()>, 
                         _1, &IDirect3D::Release));
Georg Fritzsche
Thanks for the answer. But expression with `bind` looks awful with template arguments. Better I'll just write my own deleter that will invoke `Release`.
big-z
@Kirill: According to the [documented effects](http://boost.org/doc/libs/1_43_0/libs/smart_ptr/intrusive_ptr.html#Members) of ctor/dtor/`reset()` i don't see why that check is neccessary. *(sorry for the undecided back-and-forth-rolling)*
Georg Fritzsche
@Georg, Yes, you are right. I mixed up with `shared_ptr`.
Kirill V. Lyadvinsky