何时不使用带有r值的std :: forward?

Leo*_*sky 7 c++ parameter-passing perfect-forwarding c++11

什么时候 std::forward不需要?它用于包装内部函数参数,它是templated-rvalue(也就是说,它可以是lvalue或named-rvalue).像:

template<class T>
void outer(T&& t) { 
    inner(std::forward<T>(t)); 
}
Run Code Online (Sandbox Code Playgroud)

我猜一个案例是当内部函数参数按值传递时.还有其他情况吗?当我写std::begin(std::forward<Ct>(ct))Ct是模板化的rvalue-ref 时,我有这个问题.

编辑可能的重复

如果我没记错的话,这是第三次尝试将这个4岁的问题关闭,因为一些不了解这个问题的新手.

"使用前锋的好处?" 和"何时不使用带有r值的std :: forward?" 是非常不同的问题.首先介绍初学者的r值,然后讨论高级C++用户的完美转发.我是元模板库和lambda库的作者,他们不需要详细的基础知识描述.答案中的信息与其他问题有很大不同.

GMa*_*ckG 6

当模板参数类型包含值类别时,可以进行完美转发.(如果这句话没有意义,请花一点时间熟悉手头的问题.)

鉴于:

template <typename T>
void foo(T&& x); 
Run Code Online (Sandbox Code Playgroud)

在体内foo,T将采取U或的形式U&.前者意味着我们通过了右值,后者意味着我们通过了左值.我们可以像这样转发这个事实:

template <typename T>
void foo(T&& x)
{
    bar(std::forward<T>(x));
}
Run Code Online (Sandbox Code Playgroud)

传递一个左值foo,bar得到相同的左值.通过右值foo,bar获得右值.

如果您无法区分值类别,那么转发是没有用的.只有当您使用与上述相同的方式推导出模板参数时,它才有用.是的,它在这里没用:

template <typename T>
void foo(const T& x)
{
    // if this was called as foo(1), we're none the wiser
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*sky 3

我正在回答我自己的问题,因为到目前为止我还没有得到满意的答案。如果我能得到哪怕很小的改进/补充——我会选择你的答案作为接受。

一般来说,如果能达到完美转发std::forward的效果,对内部功能是有好处的。否则就是多余的。

std::forward仅当以下任一条件为 true 时才用于包装内部函数 arg:

  • 内部函数参数是 templated-rvalue-ref (现在称为“转发引用”);
  • 内部函数有多个重载,这些重载根据参数 r/l 值进行区分;
  • 内部函数有多个重载,根据常量区分左值参数;

  • 这句话很令人困惑:“内部函数参数是模板化的右值引用”——当你有一个转发引用时,它是一个与“右值引用”完全不同的概念,称其为右值引用会引起混乱。 ,尽管它们都使用 `&amp;&amp;` 语法。也许正确的答案是,“当您将转发引用传递给另一个函数调用时,请使用`std::forward`,否则不要使用它”? (2认同)