イテレータで通常の計算を行うことはできますか?つまり、数値を追加するだけでそれをインクリメントできますか?
例として、要素vec[3]
を削除したい場合、これを実行できますか?
std::vector<int> vec;
for(int i = 0; i < 5; ++i){
vec.Push_back(i);
}
vec.erase(vec.begin() + 3); // removes vec[3] element
それは私(g ++)で動作しますが、動作するかどうかは保証かわかりません。
イテレーターがランダムアクセスイテレーターである場合に機能します(ベクターのイテレーターは reference を参照)。 STL関数 std::advance
は、一般的なイテレータを進めるために使用できますが、イテレータを返さないため、見た目がきれいであるため、可能であれば+を使用する傾向があります。
C++ 11ノート
std::next
および std::prev
、これはdoがイテレータを返すため、テンプレートランドで作業している場合は、それらを使用して汎用イテレータを進めても、クリーンなコードを保持できます。
微妙な点は、operator+
がDistance
を取ることです。つまり、符号付き整数です。符号なしでイテレータをインクリメントすると、精度が失われ、驚かれる可能性があります。たとえば、64ビットシステムでは、
std::size_t n = (1 << 64) - 2;
std::vector<double> vec(1 << 64);
std::vector<double> slice(vec.begin() + n, vec.end());
実装定義の動作につながります。 g++
またはclang
を使用すると、正規の-Wsign-conversion
または-Wall
の一部ではない警告フラグ-Wextra
を使用して、このような望ましくない変換について警告するようコンパイラーに要求できます。
回避策は、ポインタを直接操作することです
std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
それはきれいではありませんが、正しいです。場合によっては、イテレータを手動で作成する必要があります。たとえば、
std::vector<double>::iterator fromHere{vec.data() + n};
vec.erase(fromHere, vec.end());
ランダムアクセスイテレータで動作します。一般に、より一般的な std :: advance を確認することをお勧めします。この関数テンプレートの使用によるパフォーマンスへの影響を必ず理解してください。