如何访问std::vector
的{{1}}个键或值?
感谢。
编辑:我想访问实际的元素,而不仅仅是其内容的副本。基本上我想要一个参考,而不是副本。
这基本上就是我想要做的事情:
std::map
答案 0 :(得分:2)
没有一个函数可以调用来获取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
关键字开头。对此here有一个很好的解释。
希望这有帮助!
答案 1 :(得分:2)
你不能这样做,因为值和键都没有在内存中连续排列。每个键/值对在内存中独立分配。在像你这样的情况下,你必须复制周围的值。
答案 2 :(得分:0)
除了别人所说的,听起来非常像你真的想把值放到std::vector
然后对矢量进行排序;这样你就可以像你想要的那样访问内容(即通过指向它们连续数组的指针)。
请注意,这假定读数将是您的瓶颈,并且写入(即设置向量)将相对不频繁地完成。如果没有,那么你最好坚持使用std::map
,然后每次想要以这种方式使用它们时将内容复制到临时数组/向量中。
答案 3 :(得分:0)
正如其他人在他们的回答中所说,你不能以std :: vector的形式访问所有的键或值而不复制它们 - std :: map不是为这种访问形式而设计的。
根据您的情况,我会设置2个容器:
std::vector<GLuint> texture_id;
std::map<std::string, size_t> texture_map;
其中向量存储ID,而映射的值是向量中ID的索引。添加新纹理时,将ID添加到带有push_back()
的向量中,其索引存储在具有最后一个元素索引的映射条目中,例如:
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指出这个设计的缺陷。 编辑:添加示例代码