繁体   English   中英

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

[英]When not to use std::forward with r-values?

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

template<class T>
void outer(T&& t) { 
    inner(std::forward<T>(t)); 
}

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

编辑可能的重复

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

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

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

鉴于:

template <typename T>
void foo(T&& x); 

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

template <typename T>
void foo(T&& x)
{
    bar(std::forward<T>(x));
}

将左值传递给foobar获得相同的左值。 将rvalue传递给foobar获得rvalue。

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

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

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

一般来说,如果实现完美转发的效果, std::forward将对内部功能有益。 否则它是多余的。

仅当以下任何一个为真时,才使用std::forward来包装内部函数arg:

  • 内部函数参数是templated-rvalue-ref(现在称为“转发引用”);
  • 内部函数有多个重载,它们根据参数r / l-valueness进行区分;
  • 内部函数有多个重载,它们根据constness区分lvalue参数;

使用std :: forward(在形式参数上对模板化函数,其类型为T &&形式,T为模板的类型参数):

  • 当内部函数调用是外部函数中最后一次使用参数时,和
  • 当内部函数的可能重载可能会或可能不会将参数作为右值引用时。

基本原理是,当一个对象可能通过rvalue引用作为参数传递时(这是你允许使用std :: forward),它的信息内容可能会被破坏。 因此,当您确定不再使用该信息内容时,您只想这样做。

例:

#include <utility>

template <class T> void f(T &&t);
template <class T> void g(const T &t);

template <class T>
void outer(bool f_first, T &&t)
  {
    if (f_first)
      {
        f(t);
        g(t);
      }
    else
      {
        g(t);
        f(std::forward<T>(t));
      }
  }

#include <string>

void foo(std::string s)
  {
    outer(true, s);
    outer(true, s + "x");
    outer(false, s);
    outer(false, std::move(s));
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM