#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 で、コピー オン ライトの実装を禁止しているのはどれですか?
私自身が仕様を簡単に読んだところ、仕様が不十分であると思われるため、 const バージョンと非 const バージョンを混在させなくても、 と の結果を一緒に使用できるbegin()という保証はありません。end()