2012-05-29 22 views
13

以下は、C++標準に関して定義された結果を示していますか?リストが空の場合のstd :: list:begin()の動作

std::list<int> myList; 
std::list<int>::iterator myIter = myList.begin(); // any issues? 
myList.push_back(123); 
myIter++;         // will myIter point to the 123 I pushed? 

私はこれをコンパイラでテストできますが、もっと確定的な答えが必要です。

+0

これは私に、実際には、本当に考えさせてくれたので、これは良い質問だと思います。それはリストです...おそらくこれはうまくいくかもしれません...(それはもちろんありません) – jcoder

答えて

18

をすべて標準イテレータとコンテナタイプは、この点では同じように動作:

§23.2.1 [container.requirements.general] p6

begin() retu rnsコンテナ内の最初の要素を参照するイテレータ。 end()は、コンテナの過去終了値であるイテレータを返します。 コンテナが空の場合は、begin() == end()です。過去エンドイテレータ(つまり、あなたがend()から何を得る)の場合ではないです++itための前提条件として、itはdereferenceableしなければならない§24.2.3 [input.iterators]需要、中

とテーブル107、次のような定義されていない動作の恐ろしい領域に踏み込んでいます。

+0

それは 'myIter - 'だった場合、プッシュされた値を指していますか? – balki

4
std::list<int> myList; 
std::list<int> myIter = myList.begin(); 

イテレータの値は、myList.end()で初期化した場合と同じです。イテレータは、終わりを過ぎた位置に初期化されます。要素をリストにプッシュした後でも、イテレータはまだ1つの終わりを指しています。インクリメントすると、未定義の動作が呼び出されます。

UPDATE:

例えば、あなたが-D_GLIBCXX_DEBUGとGCCとのスニペットをコンパイルした場合、生成される実行可能ファイルは、中止します:

/usr/include/c++/4.6/debug/safe_iterator.h:236:error: attempt to increment 
    a past-the-end iterator. 

Objects involved in the operation: 
iterator "this" @ 0x0x7fffc9548fb0 { 
type = N11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List_iteratorIiEENSt7__debug4listIiSaIiEEEEE (mutable iterator); 
    state = past-the-end; 
    references sequence with type `NSt7__debug4listIiSaIiEEE' @ 0x0x7fffc9548fb0 
} 
zsh: abort (core dumped) ./listiter 
+0

...あなたが円形のリストを持っている場合を除いて、1つの過去の終わりはあなたに正当な始点を与えるかもしれません定義。あなたは絶対に確信しているのですか...教育を受けた推測をしていますか? – omatai

+5

@omatai: 'std :: list <>'は循環型ではありません。 – wilx

+0

ああ、私の疲れた心では、私は(二年前に)二重リンクされたリストを作るたびに、いつも "サークル"。 D'Oh!私は家に帰る必要があります... – omatai

関連する問題