2010-07-13 124 views
10

假設一些數據結構:作爲參考性病關鍵::地圖

typedef struct { 
    std::string s; 
    int i; 
} data; 

如果我使用領域data.s關鍵在地圖std::map<std::string&, data>型的加入data實例時,執行字符串被複制?擦除地圖元素是否安全,因爲引用將變爲無效?

此外,這些問題的答案也適用於unordered_map

編輯:

這是我目前的解決辦法......但加入迭代的地圖是醜陋:

typedef struct { 
    const std::string* s; 
    int i; 
} data; 

std::map<std::string, data> map; 
typedef std::map<std::string, data>::iterator iterator; 

// add an element to the map 
iterator add_element(const std::string& s) { 
    std::pair<iterator, bool> p = states.insert(std::make_pair(s, data())); 
    iterator i = p.first; 
    if(p.second) { 
     data& d = (*i).second; 
     d.s = &(*i).first; 
    } 
    return i; 
} 

回答

10

不能存儲在標準庫容器的引用 - 你的地圖應看起來像:

map <string,data> mymap; 

該映射將管理密鑰字符串和結構實例,將爲您的副本。 mapunordered_map在這方面的工作方式與所有其他標準庫容器一樣。

注意,在C++中,你不需要類型定義聲明結構:

struct data { 
    std::string s; 
    int i; 
}; 
+0

感謝您的回答。如果我想避免有兩個字符串的副本,我應該在'struct data'中使用一個引用嗎? – 2010-07-13 10:06:58

+1

另外,當你說我不能存儲引用,你的意思是STL強制複製? – 2010-07-13 10:10:16

+2

@Helltone作爲結構體或類的成員,很難正確地使用它們 - 這實際上並不是它們的意圖。相反,你應該使用一個指針,或者從結構中完全省略字符串。 – 2010-07-13 10:11:38

15

你可能想看看boost.ref。它提供了在STL-容器內使用像這樣的包裝,可以參考:

std::map<boost::reference_wrapper<std::string>, data> 

作爲C++ 11,這是標準的一部分(在此之前,實現TR1編譯器還提供在它命名空間std::tr1)。

0

您不能使用該參考。地圖可以複製內容。這是我猜實施依賴。

但與微軟的STL測試。

struct data 
{ 
      data(data const& rhs) 
      { 
       a new object will be created here 
      } 
      std::string s; 
      int i; 
}; 

將一些對象添加到地圖中,然後將運行到複製構造函數中。 這應該使您的參考無效。

0

如果您選擇指針而不是對象,我認爲不會有很大的性能提升。只有在管理需要容納在容器內的很多現有字符串對象的數據時才能執行此操作。在破壞容器之前,還必須手動管理對象的銷燬。