为什么或何时应在调用之前将可调用函数参数强制转换为右值?



到目前为止,我已经考虑过传递和调用可调用的 as

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)...);
}

我假设这种修改只影响闭包,但我仍然不明白为什么第二个版本更可取:强制转换只影响右值参数,调用时不应复制任何状态,对吗?我还检查了 std::function::operator(( 是否在&上重载,并&&通过上述代码片段的库替代来获取提示,但事实并非如此。

提前感谢您的提示和答案!

完美转发的目的是尽可能保留原始信息。

g(std::forward<Args>(args)...);将删除原始函数对象的右值/左值信息,g始终被视为左值。

这将导致可观察的效果,例如:

struct foo {
void operator()(int) & {
std::cout << "& calledn";
}
void operator()(int) && {
std::cout << "&& calledn";
}
};

foo{}(1)将调用第二个operator()。如果你使用第一种方法而不使用std::forwardf(foo{}, 1)将调用第一个operator()

最新更新