web-dev-qa-db-ja.com

C ++のstd :: invokeとは何ですか?

Callableコンセプトとstd::threadに直面したstd::bindstd::invokeについて読んでいます。

cppreferencestd::invokeについて読みましたが、何を言っているのか理解できませんでした。ここに私の質問があります:
std::invokestd::functionstd::bindおよびCallableコンセプトとは何ですか?そして、それらの関係は何ですか?

19
user3397145

_std::invoke_は、呼び出し可能なものと、それを呼び出すための引数を取り、呼び出しを行います。 std::invoke( f, args... )f(args...)を入力することのわずかな一般化であり、いくつかの追加のケースも処理します。

呼び出し可能なものには、関数ポインターまたは参照、メンバー関数ポインター、operator()を持つオブジェクト、またはメンバーデータへのポインターが含まれます。

メンバーの場合、最初の引数はthisとして解釈されます。次に、残りの引数が_()_に渡されます(member-to-member-data-caseを除く)。

INVOKEはC++標準の概念でした。 C++ 17は、それを直接行う_std::invoke_を単に公開しました。他のメタプログラミングを行うときに役立つため、一部の標準ライブラリにはすでにINVOKEの実装が既にあり、公開は基本的に無料であり、一部は具体的なことでINVOKEについて話しやすくなるため、公開されたと思われます。

Callableオブジェクトは、C++固有の詳細は別として、「呼び出すことができるもの」です。関数である必要はありません。C++には呼び出すことができる多くの型があり、表示される可能性のあるもの(読み取り:汎用コード)ごとにそれらを通過するのは問題が多く、繰り返しが多すぎます。

それが_std::invoke_の目的です-呼び出すことができる汎用オブジェクト(C++ 17によれば、Callableの概念を満たす)を簡単に呼び出すことができます。

簡単な例を考えてみましょう:

_void foo() { std::cout << "hello world\n"; };

template <bool b>
struct optionally_callable
{
        std::enable_if_t<b> operator() ()  {   std::cout << "hi again\n";   }
};

int main()
{
    auto c = [] { std::cout << "hi from lambda\n" ;};

    std::invoke(foo);
    std::invoke(c);

    auto o = optionally_callable<true>{};
    //auto o2 = optionally_callable<false>{};

    std::invoke(o);

}
_

_o2_はnot callableです。つまり、std::is_invocable<decltype(o2)>::valuefalseです。

6
edmz