связать два аргумента - PullRequest
       5

связать два аргумента

3 голосов
/ 12 августа 2010

Предположим, у меня есть следующее struct:

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

Я хочу использовать shared_ptr, как показано в следующем коде (минимальный пример):

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

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

    return 0;
}

Thisработает нормально в большинстве случаев, но страдает, если p равно 0.У меня есть следующее средство удаления, которое я хочу использовать:

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

Но следующий код выдает много ошибок (похоже, он сбрасывает все bind.hpp):

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

Что не так с моим использованием bind?

1 Ответ

5 голосов
/ 12 августа 2010

Release() взято из IUnknown - так почему бы просто не использовать это:

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

ptr.reset(p, &my_deleter);

Обратите внимание, что Boost также имеет intrusive_ptr, что выглядит более естественным здесь:

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);

Ваша настоящая проблема, вероятно, в том, что существует не шаблонная функция SafeDeleter - для специального использования функции шаблона вам нужно использовать что-то вроде:

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