我应该什么时候std ::转发一个函数调用? [英] When should I std::forward a function call?

查看:177
本文介绍了我应该什么时候std ::转发一个函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在有效现代C ++ 中看到的代码段巧妙地实现了检测原理创建功能定时器

  auto timeFuncInvocation = 
[ & func,auto&& ... params)
{
start timer;
std :: forward< decltype(func)>(func)(
std :: forward< decltype(params)>
停止定时器并记录经过的时间;
};

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




  • 根据我的理解,我们实际上是 > 看起来像一个简单的电话会做这个伎俩。

  • 还有其他情况下,我们使用完美的转发来进行函数调用吗?






这看起来像是在lambda表达式中使用熟悉的模板语法的好例子,以防我们想要 cd>

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

考虑下面的具有ref-qualified operator()重载的函数。

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

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

记住,在lambda的正文 func 是一个左值(,因为它有一个名称)。如果你没有 forward 函数参数,则不能调用&& 限定的重载。此外,如果& 限定的重载不存在,那么即使调用者传递了一个右值 foo 代码将无法编译。



Live demo


A code snippet I saw in Effective Modern C++ has a clever implementation of the instrumentation rationale to create a function timer :

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

My question is about std::forward<decltype(func)>(func)(...

  • To my understanding, we are actually casting the function to its original type, but why is this needed? It looks like a simple call would do the trick.
  • Are there any other cases where we use perfect forwarding to make a function call ?

This looks like a good use case for the use of familiar template syntax in lambda expressions in case we wanted to make the timer type a compile time constant.

解决方案

A better description of what std::forward<decltype(func)>(func)(...) is doing would be preserving the value category of the argument passed to the lambda.

Consider the following functor with ref-qualified operator() overloads.

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

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

Remember that within the body of the lambda func is an lvalue (because it has a name). If you didn't forward the function argument the && qualified overload can never be invoked. Moreover, if the & qualified overload were absent, then even if the caller passed you an rvalue foo instance, your code would fail to compile.

Live demo

这篇关于我应该什么时候std ::转发一个函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆