std::vector 反復子の無効化: 詳細な説明
std::vector の反復子の無効化の概念は、頻繁に議論されてきました。明確にするために、std::vector::erase を介してベクター要素を消去すると、消去された要素の後に厳密に配置された反復子が無効になります。
ただし、消去された要素の正確な位置における反復子の有効性は不確実なままです。論理的には、ベクトルの基礎となる実装は通常、空のスペースを埋めるために残りの要素をシフトするため、この反復子は有効なままであると想定できます。ただし、正確な動作と未定義の結果の可能性はそれほど確実ではありません。
ベクトルからの奇数の整数の削除を示す次の例を考えてみましょう:
typedef std::vector vectype;
vectype vec;
for (int i = 0; i このコードは実際にはエラーなしで実行されるように見えますが、その妥当性については議論の余地があります。
答えは、erase の動作にあります。実際、イテレータ ( 以降のすべてのイテレータを無効にします) s) 消去に渡されます。ただし、消去された要素の直後、またはそのような要素が存在しない場合は最後まで、新しい反復子を返す要素も返します。この反復子は反復を再開するために使用できます。
上記の奇数整数の削除方法は非効率的 (O(n2)) であることに注意することが重要です。各消去にはすべての整数をシフトする必要があるためです。その後の要素。消去削除イディオムは、はるかに効率的な解決策を提供します (O(n)):
bool is_odd(int x) { return (x % 2) == 1; }
vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3