字符串::是否替换了迭代器和引用?

Does string::replace invallidate iterators and references?

本文关键字:引用 迭代器 是否 替换 字符串      更新时间:2023-10-16

>您好,我已经搜索了类字符串的迭代器和引用无效,但没有找到结果。

我有这个代码:

int main(){
std::string s = "const char* manipulation in C++";
auto beg = s.cbegin();
auto& r = *s.begin();
std::cout << s << std::endl;
std::cout << "*beg: " << *beg << std::endl;
std::cout << "r: " << r << std::endl;
s.replace(beg, beg + 11, "string");
std::cout << s << std::endl;
std::cout << "*beg: " << *beg << std::endl;        
std::cout << "r: " << r << std::endl;
}

输出:

const char* manipulation in C++
*beg: c
r: c
string manipulation in C++
*beg: s
r: s

它看起来不错,但我不知道它是否是未定义的行为。 谢谢!

根据此参考:

与此对象相关的任何迭代器、指针和引用都可能是 失效。

根据 [string.require],似乎是这样:

引用

basic_­string序列元素的引用、指针和迭代器可能会因该basic_­string对象的以下用法而失效:

调用非常量成员函数,除了operator[]atdatafrontbackbeginrbeginendrend

我相信,如果你把字符串小replace,实现可能会决定减少容量,这将重新分配。

更新

根据 C++11 标准,replace使用的重载仅指定out_of_range例外。这意味着(?(,replace本身不能重新分配,因此它不能改变其容量。不过,我不确定库函数是否会抛出未特别指定的异常。

在引用的草案中,相关的重载还提到了分配器的allocate成员函数引发的异常,这意味着重新分配的可能性。我没有看到任何子句将此异常规范限制为仅替换导致原始字符串放大的情况。