#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()