0

次のように、2 つの STL リスト (L1、L2) をループしています。

list<int>::const_iterator itr1 = L1.begin();
list<int>::const_iterator itr2 = L2.begin();

for (itr1; itr1 != L1.end(); itr1++) {
   if (*itr1 < *itr2) {
     //some code
   }

}

正常にコンパイルされますが、実行すると、「式: リスト反復子は逆参照できません」と表示されます

クラスでは、独自の STL リストを記述した STL リストのモック バージョンを作成し、イテレータを逆参照するために *operator をオーバーロードしました。ただし、明らかにここでは機能していません。

イテレータを逆参照するにはどうすればよいですか、または STL リストが別の方法で行う場合は、どのように行いますか。私はこれを見ました:

http://www.sgi.com/tech/stl/List.html

ドキュメンテーションを参照し、メンバー「参照」を受け入れるものは何も見つからなかったようですが、リストの最初または最後の部分でない限り、イテレータが指しているものを参照する方法はまだわかりませんでした。

ここで何が起こっているか知っている人はいますか?ありがとうございました

ここにペーストビンがあります:

http://pastebin.com/YRddqjmN

4

5 に答える 5

3

この (実装固有の) メッセージは、無効な反復子を逆参照したことを示唆しています。これは構文/コンパイル時のセマンティクスとは何の関係もないため、コンパイラが文句を言わなかったとしても驚くことではありません。ただし、反復子には実行時のセマンティクスがあることに注意してください。この場合、コードが空のL2リストで呼び出されることに賭けitr2 == L2.end()ます。つまり*itr2、未定義の動作が発生します。幸いなことに、これはあなたの顔を爆破するのではなく、エラーメッセージを引き起こすようです.

于 2011-04-27T01:29:35.280 に答える
2
while ( *itr2 < *itr1 ) {
    itr2++;
}

そのコードには、L2 の終わりからの実行に対するチェックがありません。多分それにチェックを追加itr2 != L2.end()します。

于 2011-04-27T01:33:58.217 に答える
0

標準リスト イテレータは、リストの範囲内、つまり [ list.begin(), list.end() ) 内にある限り逆参照できますが、リストは空ではありません。

于 2011-04-27T01:29:49.123 に答える
0

他の答えは、2 つのバグのために不正なリスト イテレータが逆参照されているという正しいものです。あなたのペーストビンを見て、

この条件は逆です。

if ( (*itr1 == *itr2) && (itr2 != L2.end()) ) {

そのはず

if ( (itr2 != L2.end()) && (*itr1 == *itr2) ) {

使用する前に itr2 が有効であることを確認するため。また、最初の条件は

if ( L1.empty() && L2.empty() ) {
            cout << "Returning an empty list because the two arugment lists were empty\n\n";

論理和でなければなりません:

if ( L1.empty() || L2.empty() ) {
            cout << "Returning an empty list because at least one of the two argument lists was empty\n\n";

しかし、それは本当に必要でもありません。

(ああ、そして、標準ライブラリの一部であるset_intersectionを知っていますか?)

于 2011-04-27T01:35:00.963 に答える