#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
;非const的begin()
和end()
函数会导致内部缓冲区被复制,因为这些函数的结果可用于修改该字符串。因此,在上述代码中,begin
一开始对于s
和s2
都是有效的,但使用非const的end()
成员使得它对于产生它的容器s2
无效。上述代码在使用写时复制实现(如libstdc++)时会产生“意外”的结果。而不是
end-begin
与s2.size()
相同,libstdc++会产生另一个数字。
使
begin
不再成为对s2
的有效迭代器,即被检索的容器,是否构成“使迭代器失效”?如果查看迭代器的要求,则在调用.end()
后,它们都似乎仍然适用于此迭代器,因此begin
仍然可以作为有效迭代器,因此未被使其无效?上述代码在C++98中是否定义良好?在禁止写时复制实现的C++11中呢?
根据我自己的简短阅读规范,它似乎规定不足,因此可能没有任何保证可以将begin()
和end()
的结果一起使用,即使不混合const和非const版本。