2

私はPOD構造体のstd::vectorを作成したプログラムを書いています。構造体のメンバーの1つは、一意の識別子です。

std :: binary_searchを使用できるようにするには、構造体にoperator<を実装する必要があります。ここでのガイドラインに従って、==、!=、<、>、> =、および<=のオーバーロードの完全なセットを記述しています。

これは、私がどのように処理するかわからなかった1つの問題を提示します。ベクトルは、各構造体に割り当てた一意のIDで並べ替えられます。同じ識別子を持つ2つの構造体は同じです。ただし、2つの構造体の識別子が同じで、他のメンバーのデータが異なる場合、状況が発生する可能性があります。

これは決して起こらないはずです。比較演算子に残りのフィールドをチェックさせ、それらが異なっていてもIDが同じである場合は、例外をスローするのが適切でしょうか?どのような種類の例外が最も適切でしょうか?

4

5 に答える 5

7

これは、SCombinatorの回答を拡張したものにすぎません。

あなたが「これは決して起こらないはずだ」と言ったという事実。例外(または2つの組み合わせ)ではなく、アサートを使用することを意味します。例外はエラーを非表示にします-まあ、非表示ではありませんが、それをキャッチして続行することはできます。これは、実際には計画していなかった例外的な状況(たとえば、存在しないファイルを開こうとしている場合)に適しています。ファイルが欠落しているのは実際には論理の一部ではありません。弟が誤ってファイルを削除したり、ウイルスだと思った攻撃的なアンチウイルスなどです。これは例外的な状況です。

同じIDを持つが、それ以外は異なるメンバーが決して起こらないものである場合、それは基本的にアサーションです。これはロジックの一部であり、必要に応じて要件の一部です。例外をスローすると、これが指摘されるだけですが、実際には例外から回復する方法はありません。何かがおかしいことに気付く頃には、もう2つ遅れています。同じIDであるが異なる2つのオブジェクトがあり、どちらが正しいか、なぜ間違ったオブジェクトが存在するかなどがわかりません。あなたはおそらくそれから回復したくないでしょう。アプリケーションはすでに誤った状態にあります-2つの矛盾するオブジェクトがすでに存在します。アプリケーションは回復不可能な状態にあります。続行すると、間違った結果が得られるか、さらに悪い結果になる可能性があります。

重要なアサーションでない場合は、後で例外をスローして、アプリケーションを閉じるためのクリーンな方法を提供することもできますが、これは単なる美化です。

一般的に、私は単純なルールに従います-それが異常な状況で発生する可能性がある場合は、例外を使用します。それが決して起こらないはずの何かであり、それが起こった場合、コードのロジックに深刻な問題があることを意味する場合、私はアサーションを使用します(そしておそらく強制クラッシュ)。

于 2012-12-07T01:01:53.633 に答える
2

そのようなことが論理的なエラーである場合は、おそらく。を使用する必要がありますassert

于 2012-12-07T00:51:29.137 に答える
2

さて、あなたは自分自身にいくつかの質問をしなければなりません:

1)これはテスト中に発生する可能性がありますか(つまり、バグの通知)、通常の実行中には発生しませんか?答えが「はい」の場合は、を使用しassertます。

2)これは通常の実行時に発生しますか?発生した場合、プログラムは回復して実行を継続できますか?答えが「はい」の場合、エラーをスローし、それをキャッチして処理します。

3)これは通常の実行時に発生し、回復不能ですか?はいの場合はabort、(exit, terminate)を呼び出すか、そのようなものを呼び出すか、処理しない例外をスローします。

于 2012-12-07T00:58:39.543 に答える
1

不良データは、データの作成時に拒否する必要があります。間違いを取り除くのは比較演算子の仕事ではありません。これは、プログラムが深刻なデータ操作を行う前に行う必要があります。したがって、質問に対する答えはノーでoperator==ありoperator!=、不良データに例外をスローするべきではありません。それらは、それらに渡されるデータが有効であるという前提で書かれるべきです。

于 2012-12-07T14:07:32.907 に答える
0

mapを複製することになりますが、バイナリ検索ツリーで実装されたを使用することもできますidid繰り返しになりますが、構造体は一意であると想定されているため、構造体に格納する必要はありません。

// Example POD struct.
struct MyStruct
{
  int id; // Redundant.
  char a;     
}

std::map<int, MyStruct> myMap;
MyStruct m; m.id = 1;
myMap[m.id] = m;
// Or simply..
myMap[1] = m;
于 2012-12-07T00:58:14.260 に答える