#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'; }
This code mixes the result of begin() const with the result of end() . None of these functions are allowed to invalidate any iterators. However, I am curious if the requirement of end() change the begin iterator variable actually means that the begin variable can be used with end .
Consider a C ++ 98 implementation, copy-on-write std::string ; the non-const functions begin() and end() cause the internal buffer to be copied, because the result of these functions can be used to modify the string. Thus, begin above starts for both s and s2 , but using the non-const end() member means that it no longer works for s2 , the container that created it.
The above code produces "unexpected" results with copy-to-write implementations, such as libstdc ++. Instead of end - begin matches s2.size() , libstdC ++ produces a different number .
Does begin invalid iterator in s2 , the container from which it was extracted represents the "nullification" of the iterator? If you look at the requirements for iterators, they all look for that iterator after calling .end() , so maybe begin is still qualified as a valid iterator and thus was not invalidated?
Is the above code correct in C ++ 98? In C ++ 11, which prohibits the implementation of copy to write?
From my brief reading of the specifications, it does not seem sufficiently specified, so there can be no guarantee that the results of begin() and end() can be used together, even without mixing constants and non-const.
source share