什么是c ++中的std :: invoke?

时间:2017-04-28 12:23:28

标签: c++ c++17

我刚刚阅读了std::threadstd::bind,其中我遇到了Callable概念和std::invoke

我在cppreference上读到std::invoke,但我不明白它的含义。这是我的问题:
什么是std::invokestd::functionstd::bindCallable概念?他们之间的关系是什么?

2 个答案:

答案 0 :(得分:23)

std::invoke需要一些可调用的东西,以及调用它的参数,并进行调用。 std::invoke( f, args... )是对f(args...)的轻微概括,它还处理了一些其他案例。

可调用的东西包括函数指针或引用,成员函数指针,带有operator()的对象或指向成员数据的指针。

在成员案例中,第一个参数被解释为this。然后将剩余的参数传递给()(指向成员数据的情况除外)。

INVOKE是C ++标准中的一个概念; C ++ 17只是直接暴露了std::invoke。我怀疑它暴露的部分是因为它在进行其他元编程时很有用,部分原因是每个标准库都已经有一个INVOKE的实现并暴露它基本上是免费的,部分是因为它使得INVOKE的讨论变得更容易

答案 1 :(得分:6)

除了C ++特定的细节之外,Callable对象是可以被称为"的东西。它不一定是一个函数: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 可调用,即std::is_invocable<decltype(o2)>::valuefalse