読者です 読者をやめる 読者になる 読者になる

C++1z INVOKEコンセプトに従った関数呼び出しをするinvoke()関数

C++

C++11から入ったstd::mem_fn()関数、std::bind()関数、std::result_ofメタ関数などは、どれもINVOKEコンセプトという仕様のもとに定義されています。

これらの機能は、関数オブジェクトをただ呼び出すだけでなく、

  • メンバ関数ポインタ + レシーバー + 引数を指定してメンバ関数を呼び出したり、
  • メンバ変数ポインタ + レシーバーを指定してメンバ変数を取り出したり

といったことができます。そういった機能がINVOKEコンセプトというもので共通化されています。

C++1zでは、INVOKEコンセプトで関数呼び出しを行うstd::invoke()関数が導入されます。

#include <iostream>
#include <functional>

void f(int, char, double)
{
    std::cout << "f" << std::endl;
}

struct Functor {
    void operator()(int, char, double)
    {
        std::cout << "functor" << std::endl;
    }
};

struct X {
    int member_variable = 3;

    void member_function(int, char, double)
    {
        std::cout << "member_function" << std::endl;
    }
};

int main()
{
    // 関数
    std::invoke(f, 1, 'a', 3.14);

    // 関数オブジェクト
    std::invoke(Functor(), 1, 'a', 3.14);

    // メンバ変数
    X x;
    std::cout << std::invoke(&X::member_variable, x) << std::endl;

    // メンバ関数
    std::invoke(&X::member_function, x, 1, 'a', 3.14);
}

出力:

f
functor
3
member_function

宣言

// <functional>
namespace std {
    template <class F, class... Args>
    result_of_t<F&&(Args&&...)> invoke(F&& f, Args&&... args);
}

参照

お断り

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