ラムダ型の例外をキャッチすることは可能ですか?質問する

ラムダ型の例外をキャッチすることは可能ですか?質問する

クラスから派生した型の例外のみをスローするのが良い方法ですが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

おすすめ記事