为什么要使用 invoke helper 而不是调用 functor?
why use invoke helper rather than just call functor?
如图std::apply
we see that the standard library function std::invoke
的'possible implementation'用于调用可调用对象F
。
这种情况需要吗?如果是,是什么原因?
写作有什么好处:
template<typename F, typename ... Args>
decltype(auto) func(F &&f, Args &&... args){
return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
超过:
template<typename F, typename ... Args>
decltype(auto) func(F &&f, Args &&... args){
return std::forward<F>(f)(std::forward<Args>(args)...);
}
?
指向成员的指针是 Callable
,invoke
(或 INVOKE
,因为 soon-to-be-seven-bullet-point construct 在标准中是已知的)的魔法处理这种情况(好吧,实际上有四种,很快就会有六种情况),而函数调用语法则没有。
我想用句法示例来补充:
struct X {
int x;
int foo(int a) const { return a + x; }
};
并且您有一个 X
对象和一个指向成员函数的指针,例如:
X obj = X{1000};
auto fn = &X::foo;
需要调用func
.
使用调用语法,这行不通:
func_call(fn, obj, 24); // compiler error
error: must use '.' or '->' to call pointer-to-member function in [...]
相反,您必须解决它:
func_call([obj, fn](int a) { return (obj.*fn)(a); }, 24);
如果你有 invoke 方法,你可以这样写:
func_invoke(fn, obj, 24);
如图std::apply
we see that the standard library function std::invoke
的'possible implementation'用于调用可调用对象F
。
这种情况需要吗?如果是,是什么原因?
写作有什么好处:
template<typename F, typename ... Args>
decltype(auto) func(F &&f, Args &&... args){
return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
超过:
template<typename F, typename ... Args>
decltype(auto) func(F &&f, Args &&... args){
return std::forward<F>(f)(std::forward<Args>(args)...);
}
?
指向成员的指针是 Callable
,invoke
(或 INVOKE
,因为 soon-to-be-seven-bullet-point construct 在标准中是已知的)的魔法处理这种情况(好吧,实际上有四种,很快就会有六种情况),而函数调用语法则没有。
我想用句法示例来补充
struct X {
int x;
int foo(int a) const { return a + x; }
};
并且您有一个 X
对象和一个指向成员函数的指针,例如:
X obj = X{1000};
auto fn = &X::foo;
需要调用func
.
使用调用语法,这行不通:
func_call(fn, obj, 24); // compiler error
error: must use '.' or '->' to call pointer-to-member function in [...]
相反,您必须解决它:
func_call([obj, fn](int a) { return (obj.*fn)(a); }, 24);
如果你有 invoke 方法,你可以这样写:
func_invoke(fn, obj, 24);