简体   繁体   English

std :: map,指向映射键值的指针,这可能吗?

[英]std::map, pointer to map key value, is this possible?

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? 我想将这个指针p存储在其他地方,它对整个程序生命有效吗? 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将变为无效?

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 yes storing pointers to data members of a map element is guaranteed to be valid, unless you remove that element. 所以保证指向map元素的数据成员的指针保证有效,除非你删除元素。

First, maps are guaranteed to be stable; 首先,地图保证稳定; ie 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. 然后存储而不是字符串指针。

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::insert it 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::insert on 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. 正如皮埃尔所说,你应该存储迭代器而不是指针。

Why are you wanting to do this? 你为什么要这样做?

You can't change the value of *p, since it's const std::string. 你不能改变* p的值,因为它是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. 如果您确实更改了它,那么您可以通过更改元素的排序顺序来打破容器的不变量。

Unless you have other requirements that you haven't given here, then you should just take a copy of the string. 除非你有其他要求,你没有在这里给出,那么你应该只取一个字符串的副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM