2014-03-27 39 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! 
}