advance()
関数を使用してイテレータをインクリメントできることを知っています。また、iterator++
を使用して、イテレータを1ポジション増やします。なぜit+=2
を使用できないのですか?
int main()
{
list<int> l1{1, 2, 3, 5, 6};
list<int> l2{2, 6, 8};
auto it = l1.begin();
advance(it, 2); //works
it++; //works
// it+=2; //not work
l2.splice(l2.begin(), l1, it);
for(int a: l2) cout<<a<<" ";
cout<<endl;
return 0;
}
上記のコード here を実行できます。
operator +=
は RandomAccessIterator でのみサポートされています。一定の複雑さを持つことになっていることに注意してください。
std::list
の反復子は BidirectionalIterator であり、operator +=
をサポートしません。 (std::vector
およびstd::array
の反復子はRandomAccessIteratorです。)
RandomAccessIteratorの複雑さが一定の場合、両方とも std :: advance で使用できることに注意してください。他のInputIterator(BidirectionalIteratorを含む)に使用される場合、複雑さは線形です。つまり、std::advance
を使用することは、より一般的であり、RandomAccessIteratorの利点を自動的に利用できるため、良いアイデアです。
このイテレータでは+= 2
を使用できません。一般的な場合、std::list<>
イテレータを任意の値だけインクリメントすることは比較的非効率的操作であるためです。 +=
は、コードでこの非効率的な操作を不注意に/知らずに使用することを防ぐために、イテレータータイプに対して定義されていません。代わりに、本当にそれをしたい場合は、std::advance
を使用することになっています。これは、非効率的なことをしている可能性があるという事実を強調することを目的とした「レッドフラグ」関数です。 std::advance
は、主にコードスケッチまたはngetly-to-get-executedフォールバックコードを対象としています。本番コードでstd::advance
を無償で使用することは想定されていません。突然std::advance
に依存していることに気付いた場合、おそらくデータ構造を再設計する必要があることを意味します。基本的に、std::advance
はキャストのようなものです。使用する非常に非常に適切な理由がない限り、避けてください。
または、std::next
を使用できます
it = std::next(it, 2);
この関数は、std::advance
よりもはるかに使いやすいです。デフォルトでは、この関数はイテレーターを1ステップ進めるように設計されていますが、2番目のパラメーターを指定してそれをさらに進めることができます。繰り返しますが、2番目のパラメーターの値が一定でなく潜在的に大きい場合、「レッドフラグ」関数と見なす必要があります。 2の定数値は間違いなく許容範囲内です。