[英]Accessing std::map keys and values
您如何訪問std::map
的鍵或值的std::vector
?
謝謝。
編輯:我想訪問實際元素,而不僅僅是它們內容的副本。 本質上,我需要參考,而不是副本。
這本質上就是我想要做的:
std::map<std::string, GLuint> textures_map;
// fill map
glGenTextures( textures_map.size(), &textures_map.access_values_somehow[0] );
您無法執行此操作,因為值和鍵都沒有連續排列在內存中。 每個鍵/值對在內存中獨立分配。 在像您這樣的情況下,您必須復制周圍的值。
您無法調用一個函數來從STL映射中獲取所有鍵或值。 相反,您可以使用地圖迭代器訪問此信息:
for (map<K, V>::iterator itr = myMap.begin(); itr != myMap.end(); ++itr) {
// Access key as itr->first
// Access value as itr->second
}
如果要編寫一個將這些值包含在STL向量中的函數,則可以這樣進行:
template <typename K, typename V>
std::vector<K> GetKeys(const std::map<K, V>& m) {
std::vector<K> result;
result.reserve(m.size()); // For efficiency
for (typename std::map<K, V>::const_iterator itr = m.begin(); itr != m.end(); ++itr)
result.push_back(itr->first);
return result;
}
template <typename K, typename V>
std::vector<V> GetValues(const std::map<K, V>& m) {
std::vector<V> result;
result.reserve(m.size()); // For efficiency
for (typename std::map<K, V>::const_iterator itr = m.begin(); itr != m.end(); ++itr)
result.push_back(itr->second);
return result;
}
請注意,在這些模板函數中,迭代器的類型為
typename std::map<K, V>::const_iterator
代替
std::map<K, V>::const_iterator
這是因為const_iterator
是從屬類型 (依賴於模板參數的類型),因此出於愚蠢的歷史原因,必須以typename
關鍵字作為開頭。 有一個很好的解釋在這里 。
希望這可以幫助!
除了其他人所說的,聽起來很像您真的想將值放入std::vector
然后對向量進行排序。 這樣,您可以隨意訪問內容(即,通過指向它們的連續數組的指針)。
請注意,這是假設閱讀將成為您的瓶頸,而寫(即設置矢量)將相對不頻繁地完成。 如果不是這樣,那么您最好還是堅持使用std::map
,然后每次要以這種方式使用它們時,將內容復制到一個臨時數組/向量中。
正如其他人在回答中所說的那樣,如果不復制它們就不能以std :: vector的形式訪問所有鍵或值-std :: map並非針對這種訪問方式而設計。
對於您的情況,我將設置2個容器:
std::vector<GLuint> texture_id;
std::map<std::string, size_t> texture_map;
向量在其中存儲ID,而地圖的值是向量中ID的索引。 添加新紋理時,請使用push_back()
將ID添加到向量中,其索引存儲在帶有最后一個元素索引的地圖條目中,例如:
pair<map<string, size_t>::iterator, bool> result =
texture_map.insert(make_pair(new_texture_name, -1)); //ignore the index for now
if(result.second) { //true when the texture name isn't already in the map
texture_id.push_back(new_id);
result.first->second = texture_id.size()-1; //update the index in the map to this ID's element in texture_id
}
push_back將為舊ID保留相同的索引。 像在其他問題的答案中一樣,將所有這些內容封裝在具有添加和搜索紋理的函數的類中。
加載ID后,您可以致電:
glGenTextures( textures_id.size(), &(textures_id[0]) );
...因為std :: vector保證了元素在內存中是連續的。
編輯:更改地圖的值類型; 以前是GLuint *,指向向量的元素。 感謝Oli Charlesworth指出此設計的缺陷。 編輯:添加了示例代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.