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