سؤال

I need to be able to search for a raw pointer Thing* in a boost::bimap<shared_ptr<Thing>, int>. However, I can't call a function with the signature bm.left.find(thingRawPtr) because a smart pointer cannot be implicitly constructed from a raw pointer:

bimap<shared_ptr<Thing>, int> bm;

void f(Thing* thing)
{
    bm.left.find(thing); // (Nasty) compile error
}

What's the best way to circumvent this?

هل كانت مفيدة؟

المحلول

You have to create a smart pointer, but you can't do it the regular way, because then you would have two separately created smart pointers managing one object, and when one pointer decides to delete the Thing, the other pointer is left with a dangling pointer.

To get around this, you can create a shared_ptr with a do-nothing deleter. This is a functor that will do nothing instead of delete the object like the smart pointer wants it to. Here's a simple deleter from Boost's docs:

struct null_deleter
{
    void operator()(void const *) const
    {
    }
};

Now your code becomes:

void f(Thing* thing)
{
    bm.left.find(shared_ptr<Thing>(thing, null_deleter)); // compiles
}

But! We're using C++11, which has a handy feature called lambdas, or anonymous functions. You can use it to unclutter your code from one-off functors such as null_deleter. Using lambdas, everything above can be replaced with:

void f(Thing* thing)
{
    bm.left.find(shared_ptr<Thing>(thing, [](void*){}));
    // doesn't need null_deleter anywhere!
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top