据我了解,std::invoke
允许我执行以下操作:
std::invoke(f, arg1, arg2, ...);
有没有一种情况比简单地做更有利:
f(arg1, arg2, ...);
如果 invocable 是指向成员函数的指针,则需要执行以下操作之一:
(arg1->*f)(arg2,...);
(arg1.*f)(arg2,...);
取决于arg1
是什么。
INVOKE(及其官方库对应物std::invoke
)几乎是为了简化这种混乱而设计的。
您将使用std::invoke
来支持代码的调用方传递任何可调用对象,而不必使用 lambda 或对std::bind
的调用来调整他们的调用站点。
当您创建 lambda 并需要立即调用它时,std::invoke
非常有用。它的lambda很大,后面的括号可能很难观察到:
[] (/* args */) {
// many lines here
// ...
} (/* args */)
与
std::invoke(
[] (/* args */) {
// many lines here
// ...
},
/* args */);
试图在两个答案的基础上添加,一个是给出一个很好的理论解释,另一个是试图提供一个具体的例子。这是为什么std::invoke
使事情变得更好的一个很好的理由。
#include <functional>
#include <iostream>
struct foo
{
void echo(){std::cout << "foo" << std::endl;};
};
int main()
{
////
// Vanilla version of invoking .echo()
foo(f);
f.echo();
////
// Pointer to *class* member function version
void (foo::* pf)() = &foo::echo;
foo obj;
(obj.*pf)(); // ugly
// instead do ...
std::invoke(pf, obj);
// obj->echo(); <-- does not compile
return 0;
}
#include <iostream>
#include <functional>
template< class Callable, typename ... Args>{}
//f(args...); // if arg1 is a class object pointer
// we should use it like this(arg1.*f)(args...);
std::invoke(f, args...); // now every thing is ok
}
void foo(char c) {
std::cout << "foo calledn";
}
int main()
{
struct S {
int f1(char c) {
std::cout << "S::f1 calledn";
}
void operator()(char c) {
std::cout << "S::operator() calledn";
}
};
int (S:: * fptr)(char c) = &S::f1;
S obj;
dosomething(fptr, obj, 'a');
return 0;
}