2012-02-25 52 views
1

我有以下類型:避免臨時的std :: string來調用的boost :: unordered_map ::找到

boost::unordered_map< std::string , Domain::SomeObject > objectContainer; 

這僅僅是一個映射到某個域對象,使用std::strings作爲鍵。現在,可以構建std::string並與const char*進行比較。 (不需要明確的std::string暫時的,但也許是隱式轉換是怎麼回事?)

當我試圖做類似

void findStuff(const char* key) { 
    auto it = objectContainer.find(key); //<---build error 
} 

我主要在這裏關注的問題發生的情況是,它似乎有點矯枉過正以構建一個std::string只是爲了與一個無效的std::string進行比較,因爲std::string臨時需要擁有自己的緩衝區,將其中的const char*內容複製,然後使用它運行find()方法。

是否有一個快捷方式可以用來避免在此創建std::string臨時文件?

+1

類型我不知道「時間」在這裏是正確的字你某種星際旅行的人 – 2012-02-25 12:45:53

+0

? @KerrekSB:「星際迷航」與它有什麼關係?「Temporal」是一個真實的詞,儘管你是對的,因爲它不是正確的使用。 – 2012-02-25 13:07:26

+0

感謝您修復它,我不時混合與西班牙語 – lurscher 2012-02-25 13:16:53

回答

2

當然。再次聲明你的函數是這樣的:

void findStuff(std::string const & key); 

調用代碼現在使用std::string從一開始。

+0

Kerrek,所以如果我從你寫的東西正確推斷,你會說那你對我的問題的回答是:「不要着急避免臨時性,傳遞一個const std :: string可能暗示編譯器通過神奇的方法來避免緩衝區分配」? – lurscher 2012-02-25 13:11:44

+0

@lurscher:沒有魔法。您通過const引用傳遞字符串,而不是通過值傳遞,因此您不會複製任何內容,而是引用現有的字符串。當然,你必須在別處有一個現有的字符串。 – 2012-02-25 13:29:04

+2

@lurscher - Kerrek避免臨時的方法是首先不要有'const char *'參數。如果你在任何地方使用'std :: string',你不需要任何轉換! – 2012-02-25 13:34:38

0

如果你不想創建任何額外的std :: string,你可以逐個運行所有的鍵,並將它們與舊的strcmp進行比較。但是Kerrek的解決方案是在我看來,最好的

+0

什麼最好的解決方案?我在問是否有辦法避免暫時的。一個一個的關鍵比較完全失敗了一個unordered_map的點,它應該有O(1)的訪問權限 – lurscher 2012-02-25 13:13:42

-2

嘗試使用這樣的: -

void findStuff(const char* key) 
    { 
    std::string abc = (std::string)key; //<---build error 
    auto it = objectContainer.find(abc); // Now use "abc to find in Map 
    } 
0

你可以繼承的boost :: unordered_map並加上在「字符*」的一個版本,處理臨時STD一個找到::你的字符串。

//boost::unordered_map< std::string , Domain::SomeObject > objectContainer; 
class ObjectContainer::public boost::unordered_map< std::string , Domain::SomeObject > 
{ 
public: 
    iterator find(const char *key){const std::string constKey(key); return boost::unordered_map< std::string , Domain::SomeObject >::find(constKey);} 
    const_iterator find(const char *key)const {const std::string constKey(key); return boost::unordered_map< std::string , Domain::SomeObject >::find(constKey);} 
}; 

ObjectContainer objectContainer; 

也採取上述與一粒鹽,因爲我沒有測試過。我目前的設置VS2008與升壓1.40沒有餵養一個const char *發現問題(我也沒有使用汽車)。它對const char *和operator []函數有問題,我爲operator []函數做了類似的操作,允許像objectContainer [「key」]那樣訪問。

0

主要問題是聲明你的容器。

boost::unordered_map< std::string , Domain::SomeObject > objectContainer; 

如果放眼源,我們將看到:

template<typename Key, typename Mapped, ...> 
    class unordered_map; 
iterator find(const Key &); 

所以,你必須通過接口很強的限制。方法find始終使用Key類型作爲參數,不能在不更改容器密鑰類型的情況下更改它。

如果您確定在std :: string的初始化過程中失去了太多時間,則可以使用緩衝區(如果沒有線程)。例如:

class objectContainer : public boost::unordered_map<std::string, SomeObject> 
{ 
    std::string _buffer; 
public: 
    typedef boost::unordered_map<std::string, SomeObject> inherited; 

    objectContainer() { _buffer.reserve(1024); } 

    typename inherited::iterator find(const char * key) 
    { 
     _buffer = key; 
     return inherited::find(_buffer); 
    } 
}; 

現在,緩衝構造中分配內存只有一次,而不是每次調用時發現。

其他方式,使用自己的密鑰類型可工作的std :: string,併爲const char *,但在這種情況下,你應該用你的密鑰類型定義執行哈希(boost::hash<Key>),謂語(std::equal_to<Key>)的。

事情是這樣的:

class Key 
{ 
public: 
virtual ~Key(); 

virtual const char * key() = 0; // for hash and predicate 
}; 

// predicate 
struct equal_to_Key : binary_function <Key,Key,bool> { 
    bool operator() (const Key & x, const Key & y) const 
    { 
     return false; // TODO : compare Key here 
    } 
}; 

class CharKey : public Key 
{ 
const char * _key; 
public: 
    virtual const char * key() { return _key; } 
}; 

class StringKey : public Key 
{ 
std::string _key; 
public: 
    virtual const char * key() { return _key.c_str(); } 
}; 

現在,你有一個辦法讓const char *與哈希和謂語使用它。當你插入字符串時,你更喜歡使用StringKey。找到時 - CharKey。

boost::unordered_map< Key , Domain::SomeObject, KeyHashFunctor, equal_to_Key > objectContainer; 
void findStuff(const char* key) { 
    auto it = objectContainer.find(CharKey(key)); 
} 

但是,在這種情況下添加的虛擬功能和創建Key對象可能會降低性能比較與ObjectContainer的工作變得不舒服。

0

// < ---建立自己的錯誤

什麼錯誤?它應該按原樣編譯。 不幸的是,沒有簡單的方法來做你想做的事情。我被同樣的問題困擾了。 :(

有多種問題:參數類型的find()std::equal_tostd::hashstd::less

相關問題