C++ std::map,指向映射键值的指针,这可能吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/516007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
std::map, pointer to map key value, is this possible?
提问by michael
std::map<std::string, std::string> myMap;
std::map<std::string, std::string>::iterator i = m_myMap.find(some_key_string);
if(i == m_imagesMap.end())
return NULL;
string *p = &i->first;
Is the last line valid? I want to store this pointer p somewhere else, will it be valid for the whole program life? But what will happen if I add some more elements to this map (with other unique keys) or remove some other keys, won't it reallocate this string (key-value pair), so the p will become invalid?
最后一行有效吗?我想将此指针 p 存储在其他地方,它对整个程序生命周期都有效吗?但是如果我向这个映射添加更多元素(使用其他唯一键)或删除一些其他键会发生什么,它不会重新分配这个字符串(键值对),所以 p 将变得无效?
采纳答案by PierreBdR
First, maps are guaranteed to be stable; i.e. the iterators are not invalidated by element insertion or deletion (except the element being deleted of course).
第一,地图保证稳定;即迭代器不会因元素插入或删除而失效(当然被删除的元素除外)。
However, stability of iterator does not guarantee stability of pointers! Although it usually happens that most implementations use pointers - at least at some level - to implement iterators (which means it is quite safe to assume your solution will work), what you should really store is the iterator itself.
然而,迭代器的稳定性并不能保证指针的稳定性!尽管大多数实现通常使用指针 - 至少在某种程度上 - 来实现迭代器(这意味着假设您的解决方案可以工作是非常安全的),但您真正应该存储的是迭代器本身。
What you could do is create a small object like:
你可以做的是创建一个小对象,如:
struct StringPtrInMap
{
typedef std::map<string,string>::iterator iterator;
StringPtrInMap(iterator i) : it(i) {}
const string& operator*() const { return it->first; }
const string* operator->() const { return &it->first; }
iterator it;
}
And then store that instead of a string pointer.
然后存储它而不是字符串指针。
回答by Greg Rogers
Section 23.1.2#8 (associative container requirements):
第 23.1.2#8 节(关联容器要求):
The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
插入成员不应影响迭代器和对容器的引用的有效性,擦除成员应仅使迭代器和对已擦除元素的引用无效。
So yesstoring pointers to data members of a map element is guaranteed to be valid, unless you remove thatelement.
所以是的,存储指向地图元素的数据成员的指针保证是有效的,除非您删除该元素。
回答by drby
If you're not sure which operations will invalidate your iterators, you can look it up pretty easily in the reference. For instance for vector::insertit says:
如果您不确定哪些操作会使您的迭代器失效,您可以在参考资料中轻松查找。例如对于vector::insert它说:
This effectively increases the vector size, which causes an automatic reallocation of the allocated storage space if, and only if, the new vector size surpases the current vector capacity. Reallocations in vector containers invalidate all previously obtained iterators, references and pointers.
这有效地增加了向量大小,当且仅当新向量大小超过当前向量容量时,才会自动重新分配已分配的存储空间。向量容器中的重新分配使所有先前获得的迭代器、引用和指针无效。
map::inserton the other hand doesn't mention anything of the sort.
另一方面,map::insert没有提及任何此类内容。
As Pierre said, you should store the iterator rather than the pointer, though.
正如皮埃尔所说,你应该存储迭代器而不是指针。
回答by Richard Wolf
Why are you wanting to do this?
你为什么要这样做?
You can't change the value of *p, since it's const std::string. If you did change it, then you might break the invariants of the container by changing the sort order of the elements.
您不能更改 *p 的值,因为它是 const std::string。如果您确实更改了它,那么您可能会通过更改元素的排序顺序来破坏容器的不变量。
Unless you have other requirements that you haven't given here, then you should just take a copy of the string.
除非您有其他未在此处给出的要求,否则您应该只获取字符串的副本。