web-dev-qa-db-ja.com

C ++ 03 throw()指定子C ++ 11 noexceptとの違い

ランタイムとコンパイル時間をそれぞれチェックすること以外に、throw()noexceptの間に他の違いはありますか?

Wikipedia C++ 11 の記事は、C++ 03のthrow指定子が非推奨であることを示唆しています。
そのため、noexceptはコンパイル時にすべてをカバーするのに十分ですか?

[注: この質問 および この記事 を参照しましたが、廃止の確固たる理由が得られませんでした。]

92
iammilind

例外指定子は一般的にひどい考えです であるため、例外指定子は非推奨になりました。 noexceptが追加されたのは、例外指定子の1つの合理的に有用な使用法である:関数がいつ例外をスローしないかを知るからです。したがって、それはバイナリ選択になります。スローする関数とスローしない関数です。

noexceptはより強力なので、throw()以外のすべてのスロー指定子を削除するのではなく、noexceptが追加されました。 noexceptは、コンパイル時にブール値に解決されるパラメーターを持つことができます。ブール値がtrueの場合、noexceptが付きます。ブール値がfalseの場合、noexceptは固定されず、関数はスローする可能性があります。

したがって、次のようなことができます。

_struct<typename T>
{
  void CreateOtherClass() { T t{}; }
};
_

CreateOtherClassは例外をスローしますか? Tのデフォルトコンストラクターができる場合、それは可能性があります。どうやって伝えますか?このような:

_struct<typename T>
{
  void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};
_

したがって、CreateOtherClass()は、指定された型のデフォルトコンストラクターがスローする場合にのみスローされます。これにより、例外指定子に関する主要な問題の1つ、つまり呼び出しスタックを伝播できないことが修正されます。

throw()でこれを行うことはできません。

118
Nicol Bolas

noexceptはコンパイル時にチェックされません。

実装は、実行されたときに、包含関数が許可しない例外をスローするか、スローする可能性があるため、式を拒否してはなりません。

noexceptまたはthrow()として宣言された関数が例外をスローしようとするときの唯一の違いは、terminateを呼び出し、otheがunexpectedを呼び出し、後者のスタイルの例外処理は事実上廃止されました。

31
CB Bailey

std :: unexpected()は、動的な例外仕様に違反したときにC++ランタイムによって呼び出されます。例外仕様がこのタイプの例外を禁止している関数から例外がスローされます。

std :: unexpected()は、プログラムから直接呼び出すこともできます。

どちらの場合でも、std :: unexpectedは現在インストールされているstd :: unexpected_handlerを呼び出します。デフォルトのstd :: unexpected_handlerはstd :: terminateを呼び出します。

1
ma13