11

リストへのイテレータは、挿入と削除後も有効なままであるという事実を利用しようとしています (削除したばかりのイテレータを除く)。これもそうですかstd::list<T>::end();

次のことを試してみるとします。

typedef std::list<int> list_int;

list_int myList;
list_int::iterator iter = myList.end();

myList.push_back(1);
myList.push_back(2);
myList.push_back(3);

if(iter == myList.end()) {
    /* do things here */
} else {
    /* do different things here */
    /* I don't expect this branch to ever execute */
}

他の場所では反復子のコレクションをこのリストに格納する可能性があり、 と比較して有効性をテストするため、これは重要ですmyList.end()。挿入と削除の後でも、無効な反復子がそのまま残ることが重要です。

4

2 に答える 2

18

std::lists end iteratorの値は、リストの存続期間中は変更されません。それは常に有効であり、常に同じであり、常にリストの架空の「末尾を過ぎた」要素に対応します。これは、リストの存続期間中の任意の時点で記憶された の値が、その存続期間の他の時点でのsome_list.end()の値と常に同じであることを意味します。some_list.end()

言語仕様は明示的に述べていません。ただし、リストには、終了イテレータを無効にしたり、その値を他の場所に関連付けたりする有効な操作はまったくありません。

あなたの例では、その2番目のブランチifは決して実行されません。

私が何も見逃していなければ、同じことがstd::mapandstd::setにも当てはまります。

于 2012-10-26T03:31:28.870 に答える
0

coutIF ステートメントの各句にa を配置して、簡単なテストを試しましたか? そうすることで、最初の節 ( iter == myList.end()) が確かにtrueであることがわかります。

end() 関数のこのドキュメントに単純に基づいて推論を行うつもりです: http://www.cplusplus.com/reference/stl/list/end/。「リスト コンテナ内の末尾要素を参照するイテレータを返します」と書かれています。したがって、past-the-endを指すイテレータが返された場合、それは常にpast-the-end を指すべきではないでしょうか? この終了点の前に挿入された要素は、反復子が指している場所 (リストの最後の要素の後の場所) に影響を与えるべきではありません。

于 2012-10-26T02:50:24.523 に答える