C++1z 関数が呼び出し可能かを判定する型特性

C++1zからは、関数が呼び出せるかどうかをコンパイル時に判定する型特性として、is_callableis_nothrow_callableの2つが<type_traits>に追加されます。

// <type_traits>
namespace std {
    template <class Fn, class... ArgTypes> struct is_invocable;
    template <class R, class Fn, class... ArgTypes> struct is_invocable_r;

    template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
    template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;

    // 変数テンプレート版
    template <class Fn, class... ArgTypes> inline constexpr bool is_invocable_v
      = is_invocable<Fn, ArgTypes...>::value;
    template <class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v
      = is_invocable_r<R, Fn, ArgTypes...>::value;
    template <class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v
      = is_nothrow_invocable<Fn, ArgTypes...>::value;
    template <class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v
      = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
}

is_invocableは、関数を呼び出せる場合にはtrue_type、呼び出せない場合にはfalse_typeから派生します。is_invocable_rは、戻り値型もセットで関数が呼び出せるかを判定します。

is_nothrow_invocableは、関数が例外を投げずに(noexcept(true))呼び出せる場合にはtrue_type、そうでない場合にはfalse_typeから派生します。

これらの型特性はテンプレートパラメータとして、以下をとります:

  1. 関数のシグニチャ(関数の型と引数の型リストを合わせたもの)
  2. 戻り値の型
#include <type_traits>

struct F {
    int operator()(int, double) { return 1; }
};

struct G {
    int operator()(int, double) noexcept { return 2; }
};

int main()
{
    static_assert(std::is_invocable<F, int, double>::value);
    static_assert(std::is_invocable<G, int, double>::value);

    // Gの関数呼び出し演算子はnoexceptなので、trueとなる
    static_assert(std::is_nothrow_invocable<F, int, double>::value == false);
    static_assert(std::is_nothrow_invocable<G, int, double>::value);

    // 変数テンプレート版は::valueを指定する必要がない
    static_assert(std::is_invocable_v<F, int, double>);
}

参照

お断り

この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。