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

发布于 2024-07-13 23:31:04 字数 362 浏览 6 评论 0原文

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 将变得无效吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

臻嫒无言 2024-07-20 23:31:04

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

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

因此,存储指向映射元素数据成员的指针保证是有效的,除非您删除该元素。

Section 23.1.2#8 (associative container requirements):

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.

倒带 2024-07-20 23:31:04

首先保证地图稳定; 即迭代器不会因元素插入或删除而失效(当然被删除的元素除外)。

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

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

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

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

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.

夜血缘 2024-07-20 23:31:04

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

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

另一方面, map::insert 没有提及任何内容那种。

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

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:

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.

As Pierre said, you should store the iterator rather than the pointer, though.

芯好空 2024-07-20 23:31:04

你为什么要这样做?

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

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

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.

Unless you have other requirements that you haven't given here, then you should just take a copy of the string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文