3

次のコードでtrycatchが必要かどうかを調べようとしていました。

std::vector<int> values;
// ignore that this can throw std::bad_alloc
values.push_back(1);
try {
    for (std::vector<int>::iterator iter = values.begin();
         iter != values.end(); ++iter) {
         ++(*iter);
    }
} catch (const std::bad_alloc&) { 
    // Is this needed?
}

C ++ 1998標準を調べると、これを示唆する唯一のヒントは、次の文を含むセクション23.1「コンテナ要件」の箇条書き8です。

この引数のコピーは、各コンテナーオブジェクトの存続期間中に、これらのコンストラクターおよびすべてのメンバー関数によって実行されるメモリ割り当てに使用されます。

私の解釈では、コンテナ内のすべてのメンバー関数がアロケータを呼び出すことができるため、すべてのメンバー関数がstd::bad_allocをスローできます。私は過度に妄想的ですか、それとも本当にそうですか?

4

3 に答える 3

4

さらに読み続けると、23.1 / 10が見つかります。これは、例外をスローできるタイミングに関するコンテナの要件を示しています。特に、次のようになります。

  • いいえerase()pop_back()またはpop_front()関数は例外をスローします。
  • 返されたイテレータのコピーコンストラクタまたは代入演算子は例外をスローしません。

あなたが本当にパラノイアであるなら、あなたはとの可能性、そしてイテレータの増分でさえ投げることを考慮すべきbegin()ですend()。ただし、標準コンテナの適切な実装では、複雑なことを行う必要はありません。

于 2012-04-19T11:15:30.953 に答える
2

理論的にはそうです、標準ライブラリコンテナのメンバー関数はすべてをスローできbad_allocます。

ほとんどの標準コンテナ自体は、()を除いて例外をスローしませんstd::vector::at()が、メモリ割り当ての失敗またはユーザー定義操作の例外に対して例外をスローできます。

私はあなたの恐れがpush_back()あなたの例の場合にそれを投げることであると思います、そうでなければそうですあなたは妄想的です。begin()ただし、これは実装の詳細です。実際には、イテレータ( 、 )を取得しているだけの場合、ほとんどの実装は割り当てを試みませんend()

于 2012-04-19T10:59:56.797 に答える
0

私は標準でより具体的なものを見つけられなかったので、証拠がない場合、技術的にはどのコンテナメソッドでもスローできると結論付ける必要がありbad_allocます。

コンテナ自体に関する限り、心配しbeginたり投げたりすることはありませんが、もう1つの厄介な点があります。それはイテレータの実装です。endイテレータがクラスタイプの場合、理論的には、そのようなインスタンスの構築(または割り当て)は非常にうまくいく可能性があります。したがって、ランダムに選択された標準ライブラリの実装がスローされる可能性は低いと思いますが、実際にそれを除外することはできません。

于 2012-04-19T11:11:52.330 に答える