2014-03-27 46 views
5

我需要能够在boost::bimap<shared_ptr<Thing>, int>中搜索原始指针Thing*。但是,我不能把带有签名bm.left.find(thingRawPtr)一个功能,因为一个智能指针不能隐从原始指针构成:在智能指针的bimap中查找原始指针

bimap<shared_ptr<Thing>, int> bm; 

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

什么是规避这一目标的最佳方式是什么?

+0

+1一个最好的自我回答Q&A我已经看到了她很长一段时间! –

+0

真的很有趣,感谢分享。 – streppel

回答

6

您必须创建一个智能指针,但不能以常规方式进行,因为那样您将有两个单独创建的管理一个对象的智能指针,并且当一个指针决定删除Thing时,另一个指针留下一个悬挂指针。

要解决这个问题,您可以创建一个shared_ptr,其中包含一个无所事事 deleter。这是一个仿函数,它不会像智能指针想要的那样删除对象。这里有一个简单的删除器从Boost's docs

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

现在你的代码变成:

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

但是!我们正在使用C++ 11,它具有一个称为lambdas的方便功能或匿名函数。您可以使用它来从一次性仿函数中解开代码,如null_deleter。使用lambda表达式,高于一切可以替换为:

void f(Thing* thing) 
{ 
    bm.left.find(shared_ptr<Thing>(thing, [](void*){})); 
    // doesn't need null_deleter anywhere! 
}