据我了解,
std::invoke
允许我做类似的事情:
std::invoke(f, arg1, arg2, ...);
有没有比简单地这样做更有利的场景:
f(arg1, arg2, ...);
如果可调用对象是指向成员函数的指针,那么您需要执行以下操作之一:
(arg1->*f)(arg2,...);
(arg1.*f)(arg2,...);
取决于
arg1
是什么。
INVOKE(及其官方图书馆对应物
std::invoke
)几乎就是为了简化这种混乱而设计的。
您可以使用
std::invoke
来支持代码的调用者传递 any 可调用,而不必使用 lambda 或对 std::bind
的调用来调整其调用站点。
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 called\n";
}
int main()
{
struct S {
int f1(char c) {
std::cout << "S::f1 called\n";
}
void operator()(char c) {
std::cout << "S::operator() called\n";
}
};
int (S:: * fptr)(char c) = &S::f1;
S obj;
dosomething(fptr, obj, 'a');
return 0;
}