🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1010閲覧

vector iterator past end 例外を防ぐ方法でこの方法は正しいのかどうか?知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/02/12 08:37

提示コードですがvector iterator past end という例外を防ぐための手段としてないはずの次の要素を指してしまったらブレイクするというコードで防いでいるのですがこれは正しいのでしょうか?

cpp

1 2 for (std::vector<Bullet>::iterator itr = bullet->begin(); itr != bullet->end(); itr++) 3 { 4 glm::ivec2 pos = itr->getPosition(); 5 if (pos.x > SCREEN_WIDTH - 200) 6 { 7 itr = bullet->erase(itr); 8 if (itr == bullet->end()) 9 { 10 break; 11 } 12 13 } 14 else 15 { 16 itr->Update(); 17 } 18 } 19

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

そのようなコードでは全要素を走査できない可能性がある.

例えば,

C++

1std::vector<int> Vec{ 10,5,20,30,40,5 };

なるvectorから,値が5である要素は除去し,それ以外の要素値を表示したいとしよう.
これを以下のように書くと,20が表示されない結果となる.
すなわち,値が20である3番目の要素に関する処理が行われないことになってしまう.

C++

1std::vector<int> Vec{ 10,5,20,30,40,5 }; 2 3for( auto i=Vec.begin(); i!=Vec.end(); ++i ) 4{ 5 if( *i == 5 ) 6 { 7 i = Vec.erase( i ); 8 if( i == Vec.end() )break; 9 } 10 else 11 { std::cout << *i << " "; } 12}

解決策:
こんな感じで.

C++

1for( auto i=Vec.begin(); i!=Vec.end(); /*NOP*/ ) 2{ 3 if( *i == 5 ) 4 { i = Vec.erase( i ); } 5 else 6 { 7 std::cout << *i << " "; 8 ++i; 9 } 10}

1回のループですべてを行わずとも良いのであれば,単純に2ステップに分けた方がわかりやすいかもしれない.

C++

1//要らない要素を捨てる 2Vec.erase( std::remove(Vec.begin(),Vec.end(),5), Vec.end() ); 3//残った要素に関して処理を行う 4for( auto v : Vec ){ std::cout << v << " "; }

投稿2021/02/12 09:16

編集2021/02/12 09:27
fana

総合スコア11985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/02/12 10:57

//  弾が画面の外に出たら消す for (std::vector<Bullet>::iterator itr = bullet->begin(); itr != bullet->end(); ) { glm::ivec2 pos = itr->getPosition(); if ( pos.x > SCREEN_WIDTH || pos.x < 0 || pos.y > SCREEN_HEIGHT / 2 || pos.y < -SCREEN_HEIGHT) { printf("あああ\n"); itr = bullet->erase(itr); if (itr == bullet->end()) { break; } } else { itr->Update(); itr++; } } このよにしましたが正しいのでしょうか?
退会済みユーザー

退会済みユーザー

2021/02/12 11:20

またメモリ容量が数メガ増えるそこで止まるというちょっとへんな感じがするのですがこの場合はどうなのでしょうか?
int32_t

2021/02/15 00:03

メモリが増えて止まる、というのはこの質問とまるで関係がありませんね。
fana

2021/02/15 01:48

> 正しいのでしょうか? まず,どのような動作をするはずのコード記述であるのか,ということを把握し, 次に,その通りの動作をしているかどうかを確認することを行ってください. その結果をもって,正しいか否かを判断してください.
guest

0

参考: イテレート中に要素を削除する (C++11) | vector::erase - cpprefjp C++日本語リファレンス

C++

1for (auto itr = bullet->begin(); itr != bullet->end();) { 2 auto pos = itr->getPosition(); 3 if (pos.x > SCREEN_WIDTH - 200) { 4 itr = bullet->erase(itr); 5 } else { 6 itr->Update(); 7 ++itr; 8 } 9}

参考先のサイトよりうまく説明できませんので、私から説明はありません。

投稿2021/02/14 08:56

raccy

総合スコア21737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問