簡體   English   中英

訪問std :: map鍵和值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM