c++ - 引用失效保证会自动应用于指针吗?
问题描述
考虑以下代码:
std::map<int, int> m;
int &ref = m[0];
int *ptr = &m[0];
m.insert({1,2});
std::cout << ref; // #1
std::cout << *ptr; // #2
对于像这样的关联容器std::map
,标准说:
insert 和 emplace 成员不应影响迭代器的有效性和对容器的引用,...
这意味着#1
绝对可以。但是,我不太确定#2
.
这个问题在十多年前就已经被问及并得到了回答。
接受的答案说#2
在技术上是不允许的,但在实践中会起作用。
一致的答案(赞成票的数量是接受的答案的两倍多)说#2
是可以的,只需说上面的标准引用暗示指针也不会失效。
这个问题也至少有六个相对较新的副本,其中大多数都有答案,而且他们都说没问题#2
,通常是引用上面相同的标准文本。
我不认为这是正确的。据我了解,引用不是指针,一个不能替代另一个,无论它们是否相互实现。作为比较,以下是该标准在重新散列时对无序关联容器中元素的引用有效性的说明:
重新散列使迭代器无效,...,但不会使指针或对元素的引用无效。
这明确地保证了指针的有效性,表明引用的有效性并不自动暗示它。
那么语言说没问题#2
吗?它的有效性是否暗示了它#1
?
解决方案
正如许多评论所说,这可能是一个轻微的标准错误措辞,标准也暗示了指针。但是,如果您想了解它的语言律师,请采取以下措施:不能重新分配参考(不是标准本身,而是我发现的官方来源:https ://isocpp.org/wiki/faq/references#reseating -参考)。也就是说,一旦引用指向一个对象,该引用将始终指向该对象。正如此处的标准所述:https ://eel.is/c++draft/intro.object ,对象在其整个生命周期中占据给定的存储区域。如此处所述:https ://eel.is/c++draft/basic.compound,指针指向其对象的第一个字节的地址。因此,如果引用仍然有效,因为它不能重新分配给另一个对象,它指向的对象还没有结束它的生命周期,所以它占用的内存仍然有效并由该对象持有,所以指针指向到开头那段记忆依然有效。因此,在标准中概述的 C++ 抽象机规则内,指针仍然有效。
推荐阅读
- reactjs - 无法将输入图片数据保存在状态变量 React.js 中
- mysql - WAMP:使用 .MYD、.frm、.MYI、db.opt 恢复数据库
- r - 如何找到与功能相关的包
- python - 创建一个 api 来公开使用 fast.ai CNN 创建的 dl 模型
- python - 质心 Voronoi 镶嵌
- json - Discord.py 如何使用 json 来存储用户 ID 并且仅存储用户 ID
- authentication - 是否应该在注销时删除刷新令牌?
- sql - 在 SQL 中。为什么这个带有通配符的“Like”语句不起作用?
- r - R grep 最终的外部括号集
- python - python - 如何使用多处理递归计算路径中的文件数