C++1zからは、noexcept
による関数の例外仕様が、型の一部として扱われるようになります。
互換性のためにnoexcept
な関数ポインタから非noexcept
な関数ポインタには変換できます。しかし、非noexcept
な関数ポインタからnoexcept
な関数ポインタには、変換できません。
void f() noexcept; void g(); void(*p1)() noexcept = f; // OK void(*p2)() = f; // OK : noexceptから非noexceptへの変換 //void(*p3)() noexcept = g; // コンパイルエラー : 非noexceptからnoexceptに変換できない
これは、ラムダ式も同様になります。
void(*p1)() noexcept = []() noexcept {}; // OK void(*p2)() = []() noexcept {}; // OK //void(*p3)() noexcept = [](){}; // コンパイルエラー
noexcept
の違いによって関数をオーバーロードすることはできません。(戻り値の型と同様)
この仕様による破壊的な影響として、C++14まで有効だった以下のコードは、C++1zではコンパイルエラーになります:
void g1() noexcept; void g2(); template<class T> int f(T*, T*); int x = f(g1, g2); // コンパイルエラー : g1とg2の型が一致しない (関数テンプレートの推論失敗)
参照
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。