リストを変更してリストが空であれば、std :: listの逆過去エンドイテレータは無効になります。しかし、言語仕様リストによると、push_backはイテレータには影響しません。std list逆反復子の過去イテレータは、リストが空の場合に無効化されます。
コンテナの最後に指定された要素の値を追加します。 1)新しい要素は、値のコピーとして初期化されます。 2)値が新しい要素に移動されます。 イテレータまたは参照は無効になりません。
これは私がlanguage specに気付いたとおりです。下のリストの例では、別の方法で動作を見つけることができます。
//Add or replace an element using reverse iterator
void addOrReplaceRev(std::list<int>& list, int val)
{
auto rit = std::find(list.rbegin(), list.rend(), val);
list.push_back(val); //invalidates the rend() iterator, if list empty
if(rit != list.rend()) //remove if the value existed earlier
list.erase((++rit).base());
}
void addOrReplace(std::list<int>& list, int val)
{
auto rit = std::find(list.rbegin(), list.rend(), val);
bool shouldErase = rit != list.rend(); //save the result before modification
list.push_back(val);
if(shouldErase) //All good, as we use saved query result
list.erase((++rit).base());
}
int main()
{
std::list<int> mylist1;
std::list<int> mylist2 = {1,2,4,5};
addOrReplaceRev(mylist1, 3); //empty list messes up with rev iters
addOrReplaceRev(mylist2, 3); //non-empty lists are fine
printf("SIZES %d:%d\n", mylist1.size(), mylist2.size());
std::list<int> mylist3;
std::list<int> mylist4 = {1,2,4,5};
addOrReplace(mylist3, 3);//if results are saved
addOrReplace(mylist4, 3);
printf("SIZES %d:%d\n", mylist3.size(), mylist4.size());
}
プログラムの出力は
SIZES 0:5
SIZES 1:5
。注:私は前方/定期的なイテレータを使用する場合、私は、この動作は表示されません。私はgcc 4.9.2コンパイラを使用しています。これは期待されているのか、コンパイラのバグですか?
`
名前に「イテレータ」があるにもかかわらず、コンテナのイテレータに適用される保証が必ずしもその逆イテレータに当てはまるとは限りません。 – user2357112