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

时间:2009-02-05 14:02:48

标签: c++ stl pointers map

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;

最后一行有效吗? 我想将这个指针p存储在其他地方,它对整个程序生命有效吗? 但是如果我向这个地图添加更多元素(使用其他唯一键)或删除其他一些键会发生什么情况,它不会重新分配这个字符串(键值对),那么p将变为无效?

4 个答案:

答案 0 :(得分:52)

第23.1.2节#8(关联容器要求):

  

插入成员不应影响迭代器的有效性和对容器的引用,并且擦除成员应仅使迭代器和对已擦除元素的引用无效。

所以 yes 保证指向map元素的数据成员的指针保证有效,除非你删除那个元素。

答案 1 :(得分:19)

首先,地图保证稳定;即元素插入或删除不会使迭代器失效(当然,除了要删除的元素)。

然而,迭代器的稳定性并不能保证指针的稳定性!尽管通常会发生大多数实现使用指针 - 至少在某种程度上 - 来实现迭代器(这意味着假设您的解决方案可以正常工作),您应该存储的是迭代器本身

你可以做的是创建一个小对象,如:

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;
}

然后存储而不是字符串指针。

答案 2 :(得分:1)

如果您不确定哪些操作会使您的迭代器失效,您可以在reference中轻松查找。例如,对于vector::insert,它说:

  

这有效地增加了向量大小,当且仅当新向量大小超过当前向量容量时,这导致分配的存储空间的自动重新分配。向量容器中的重新分配使以前获得的所有迭代器,引用和指针无效。

另一方面,

map::insert没有提到任何类似的东西。

正如皮埃尔所说,你应该存储迭代器而不是指针。

答案 3 :(得分:0)

你为什么要这样做?

你不能改变* p的值,因为它是const std :: string。如果您确实更改了它,那么您可以通过更改元素的排序顺序来打破容器的不变量。

除非您有其他要求,否则您应该只获取该字符串的副本。