我为什么要使用std :: forward?

Dea*_*ean 5 c++ c++11

在下面的代码中,为什么我应该std::forward在传递参数时使用?

class Test {
  public:
  Test() {
      std::cout << "ctor" << std::endl;
  }
  Test(const Test&) {
      std::cout << "copy ctor" << std::endl;
  }
  Test(const Test&&) {
      std::cout << "move ctor" << std::endl;
  }
};

template<typename Arg>
void pass(Arg&& arg) {
    // use arg..
    return; 
}

template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
    // use arg...
    return pass(args...); // why should I use std::forward<Arg>(args)... ?
}

int main(int argc, char** argv)
{
    pass(std::move<Test>(Test()));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

带或不带的代码std::forward不显示任何复制/移动.

Nia*_*all 9

std::forward关于它的作用和方式(例如这里这里)有很多好的帖子.

简而言之,它保留了其参数的值类别.完美转发是为了确保提供给函数的参数被转发到另一个函数(或在函数内使用),其具有与最初提供的相同的值类别(基本上是r值与l值).它通常与模板函数一起使用,其中可能发生了引用折叠(涉及通用/转发引用).

考虑下面的代码示例.删除std::forward将打印输出requires lvalue并添加std::forward打印输出requires rvalue.该func基于它是否是一个右值或左值超载.在没有std::forward调用不正确的过载的情况下调用它.将std::forward需要在这种情况下,pass被称为与右值.

#include <utility>
#include <iostream>
class Test {
  public:
  Test() {
      std::cout << "ctor" << std::endl;
  }
  Test(const Test&) {
      std::cout << "copy ctor" << std::endl;
  }
  Test(Test&&) {
      std::cout << "move ctor" << std::endl;
  }
};

void func(Test const&)
{
    std::cout << "requires lvalue" << std::endl;
}

void func(Test&&)
{
    std::cout << "requires rvalue" << std::endl;
}

template<typename Arg>
void pass(Arg&& arg) {
    // use arg here
    func(std::forward<Arg>(arg));
    return; 
}

template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
    // use arg here
    return pass(std::forward<Args>(args)...);
}

int main(int, char**)
{
    pass(std::move<Test>(Test()));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @user3834459 取决于函数的作用。如果两个重载之间的功能需要(或针对)值类别进行优化,那么可以,否则可能不需要。一般来说,考虑到这两个重载,我们可以假设存在一些差异,并且最好调用正确的版本。 (2认同)