我刚刚阅读了std::thread
和std::bind
,其中我遇到了Callable
概念和std::invoke
。
我在cppreference上读到std::invoke
,但我不明白它的含义。这是我的问题:
什么是std::invoke
,std::function
,std::bind
和Callable
概念?他们之间的关系是什么?
答案 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)>::value
为false
。