クラスから派生した型の例外のみをスローするのが良い方法ですがstd::exception
、C++ では何でもスローすることが可能です。以下の例はすべて有効な C++ です。
throw "foo"; // throws an instance of const char*
throw 5; // throws an instance of int
struct {} anon;
throw anon; // throws an instance of not-named structure
throw []{}; // throws a lambda!
最後の例は興味深いもので、別のクラスや関数を定義しなくても、キャッチ サイトで実行するコードを渡すことができる可能性があります。
しかし、ラムダ (またはクロージャ) をキャッチすることは可能なのでしょうか?catch ([]{} e)
動作しません。
更新(2022/11/14):
見るここC++20 の機能を考慮した私自身の回答。
ベストアンサー1
例外ハンドラーはタイプに基づいて一致し、例外オブジェクトをハンドラーに一致させるために行われる暗黙的な変換は、他のコンテキストよりも制限されています。
各ラムダ式は、周囲のスコープに固有のクロージャ型を導入します。そのため、単純な試みは機能しません[]{}
。全く違うタイプthrow 式とハンドラーで!
しかし、あなたの言う通りです。C++ では、任意のオブジェクトをスローできます。したがって、事前にラムダを例外ハンドラに一致する型に明示的に変換すると、任意の呼び出し可能オブジェクトを呼び出すことができます。たとえば、次のようになります。
try {
throw std::function<void()>{ []{} }; // Note the explicit conversion
} catch(std::function<void()> const& f) {
f();
}
これは興味深いユーティリティかもしれませんが、 から派生していないものをスローすることに対しては注意が必要です。より良い選択肢は、 から派生し、呼び出し可能オブジェクトを保持できるstd::exception
型を作成することです。std::exception