我什么时候应该std ::转发函数调用?

Nik*_*iou 9 c++ lambda perfect-forwarding c++14 forwarding-reference

我在Effective Modern C++中看到的代码片段巧妙地实现了创建函数计时器工具原理:

auto timeFuncInvocation = 
    [](auto&& func, auto&&... params)
    {
        start timer; 
        std::forward<decltype(func)>(func)(
            std::forward<decltype(params)>(params)...); 
        stop timer and record elapsed time; 
    };
Run Code Online (Sandbox Code Playgroud)

我的问题是关于 std::forward<decltype(func)>(func)(...

  • 据我了解,我们实际上是在铸造的功能,它的原始类型,但是这是为什么需要?看起来简单的调用就可以了.
  • 还有其他情况我们使用完美转发来进行函数调用吗?

对于在lambda表达式使用熟悉的模板语法,这似乎是一个很好的用例,以防我们想要使计时器类型成为编译时常量.

Pra*_*ian 12

更好地描述std::forward<decltype(func)>(func)(...)正在做的事情将保留传递给lambda的参数的值类别.

考虑以下具有ref-qualified operator()重载的仿函数.

struct foo
{
    void operator()() const &&
    { std::cout << __PRETTY_FUNCTION__ << '\n'; }

    void operator()() const &
    { std::cout << __PRETTY_FUNCTION__ << '\n'; }
};
Run Code Online (Sandbox Code Playgroud)

请记住,在lambda的主体内func是一个左值(因为它有一个名字).如果没有forward函数参数,&&则永远不能调用限定的重载.此外,如果&缺少限定的重载,那么即使调用者通过了rvalue foo实例,您的代码也将无法编译.

现场演示