#include <string>
#include <iostream>
int main() {
std::string s = "abcdef";
std::string s2 = s;
auto begin = const_cast<std::string const &>(s2).begin();
auto end = s2.end();
std::cout << end - begin << '\n';
}
此代码将 的结果begin() const
与 的结果混合在一起end()
。这些函数都不允许使任何迭代器无效。但是我很好奇end()
不使迭代器变量无效的要求是否begin
实际上意味着该变量begin
可用于end
.
考虑一个 C++98,写时复制的实现std::string
;非常量begin()
和end()
函数会导致复制内部缓冲区,因为这些函数的结果可用于修改字符串。所以begin
上面开始对s
and都有效s2
,但是使用非常量end()
成员导致它不再对s2
生成它的容器有效。
上面的代码使用写时复制实现(例如 libstdc++)产生“意外”结果。libstdc++不是end - begin
与 相同,而是产生另一个数字。s2.size()
是否导致
begin
不再是有效的迭代器进入s2
,它是从中检索的容器,构成“无效”迭代器?如果您查看对迭代器的要求,它们似乎在.end()
被调用后都适用于这个迭代器,所以也许begin
仍然有资格作为一个有效的迭代器,因此没有被无效?上面的代码在 C++98 中定义得很好吗?在 C++11 中,哪个禁止写时复制实现?
从我自己对规范的简要阅读来看,它似乎没有指定,因此可能无法保证begin()
and的结果end()
可以一起使用,即使没有混合 const 和非 const 版本。