c++ - 在我的代码中使用指向 STL 容器元素的指针?
问题描述
将某个类的元素存储在标准容器中,然后让其他一些类存储指向它们的指针是一个好主意/风格吗?
假设我有课程A
和std::set<A>
. 然后我创建B
具有A*
成员的类,并且该指针指向A
集合中的一些。这可以保证在标准库中工作吗?和怎么std::map
样?std::unordered_set
std::unordered_map
例如:
class A {};
std::set<A> set; //then fill with some elements
class B{
A* a;
};
B b;
B.a = &(*set.begin());
解决方案
毫无疑问,检查文档是个好主意。
例如std::set
:插入
没有迭代器或引用无效。如果插入成功,则在节点句柄中保存的元素的指针和引用无效,并且在提取之前获得的对该元素的指针和引用变为有效。(C++17 起)
可以读取类似的擦除:
对已擦除元素的引用和迭代器无效。其他引用和迭代器不受影响。
因此,从此(以及其他函数的文档)可以安全地得出结论,只要您不从集合中删除元素,就可以使用引用(和指向元素的指针)。
如果我们对 unordered_set 进行相同检查:插入:
如果由于插入而发生重新散列,则所有迭代器都将失效。否则迭代器不受影响。引用不会失效。仅当新元素数大于 max_load_factor()*bucket_count() 时才会发生重新散列。如果插入成功,则在节点句柄中保存的元素的指针和引用无效,并且在提取之前获得的对该元素的指针和引用变为有效。(C++17 起)
擦除也一样:
对已擦除元素的引用和迭代器无效。其他迭代器和引用不会失效。
所以在这里我们也可以得出结论,只要元素存储在 unordered_set 中,获取指向元素的指针应该是安全的。
我将 unordered_map 留给您验证,但是由于 std::unordered_set 是 std::unordered_map 的一个特例,没有值,我希望它的行为类似。
编辑:这是否是一个好主意很难说。容器带有保证和要求。如果这些符合您的用例,那么值得一试。根据我的经验,我建议使用特定名称将这些东西封装在某个类中,并公开您需要使用的东西。这样,如果您决定更改实施,您就会知道您提供了什么以及不需要什么。
推荐阅读
- jquery - 当我切换到不同的页面时,如何专注于导航栏中的项目?
- javascript - 外部 Javascript 未在 VSCode 中加载
- python - 在 PHP cURL 上接收“您的防伪令牌无效”但在 Python 请求中没有
- lambda - 仅使用 lambda 和内置的高阶列表函数返回给定列表的子列表
- c# - 按钮的孩子
- c# - 在 MongoDb c# -Update Arrays 中更新多个文档
- indexing - 索引中的 arangodb 查询值
- python - python SharedMemory 进程间持久化
- javascript - 将哈希数组转换为javascript中的值数组
- python - 如何从 python 中的名称中获取命名元组实例?