引用失效保证会自动应用于指针吗?

cig*_*ien 11 c++ pointers reference language-lawyer

考虑以下代码:

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
Run Code Online (Sandbox Code Playgroud)

对于像 这样的关联容器std::map,标准

insert 和 emplace 成员不应影响迭代器的有效性和对容器的引用,...

这意味着#1绝对没问题。但是,我不太确定#2


十多年前,这个问题已经被提出和回答。

接受的答案说#2在技​​术上是不允许的,但在实践中会起作用。

共识答案(赞成票数是接受的答案的两倍多)说#2是可以的,简单地说,上述标准引用暗示指针也没有失效。

这个问题至少还有六个相对较新的副本,其中大多数都有答案,并且所有人都说没问题#2,通常是引用上面相同的标准文本。


我不认为这是正确的。据我了解,引用不是指针,一个不能替代另一个,无论它们是否相互实现。作为对比,下面是标准有关指称在无序关联容器元素,在换汤不换药的有效性:

重新散列使迭代器无效,...,但不会使对元素的指针或引用无效。

这明确地保证了指针的有效性,表明引用的有效性并不自动暗示它。


那么语言说#2可以吗?它是由 的有效性所暗示的#1吗?

Ano*_*847 7

正如许多评论所说,这可能是一个轻微的标准误用,该标准也暗示了指针。但是,如果你想进入它的语言律师,请考虑:参考不能重新分配(不是标准本身,而是我找到的官方来源:https : //isocpp.org/wiki/faq/references#reseating -参考)。也就是说,一旦引用指向一个对象,该引用将始终指向该对象。正如此处的标准所述:https : //eel.is/c++draft/intro.object,对象在其整个生命周期中占据给定的存储区域。如此处所述:https : //eel.is/c++draft/basic.compound,指针指向其对象的第一个字节的地址。因此,如果引用仍然有效,因为它不能重新分配给另一个对象,它指向的对象还没有结束其生命周期,所以它占用的内存仍然有效并由该对象持有,因此指向的指针到开头那段记忆仍然有效。因此,在 C++ 抽象机的规则内,如标准中所述,指针仍然有效。