到目前为止,我已经考虑过传递和调用一个Callable作为
template <class Fct, class... Args> void f(Fct&& g, Args&&... args)
{
g(std::forward<Args>(args)...);
}
是要走的路。现在,在本讲座(第34分钟)和std :: invoke示例实现中,我看到了上述片段的等效内容,该片段在调用可调用对象之前有条件地将其转换为右值引用,
template <class Fct, class... Args> void f(Fct&& g, Args&&... args)
{
std::forward<Fct>(g)(std::forward<Args>(args)...);
}
我假设此修改仅影响闭包,但我仍然不明白为什么第二个版本更可取:强制转换仅影响rvalue参数,调用时不应复制任何状态,对吗?我还检查了std :: function :: operator()是否被重载,&
并&&
通过上述片段的替代库获取提示,但事实并非如此。
在此先感谢您的提示和答案!
完美转发的目的是尽可能保留原始信息。
g(std::forward<Args>(args)...);
将删除原始函数对象的右值/左值信息,g
将始终被视为左值。
这将导致可观察到的效果,例如:
struct foo {
void operator()(int) & {
std::cout << "& called\n";
}
void operator()(int) && {
std::cout << "&& called\n";
}
};
foo{}(1)
将调用第二个operator()
。如果您不使用第一种方法std::forward
,f(foo{}, 1)
将调用第一种operator()
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句