为什么要使用std :: forward? [英] Why should I use std::forward?

查看:91
本文介绍了为什么要使用std :: forward?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the code below, why should I use std::forward when passing around arguments?

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;
}

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

The code with or without std::forward doesn't show any copy/move around.

推荐答案

关于 std :: forward 的功能及其工作方式(例如此处).

There are a number of good posts on what std::forward does and how it works (such as here and here).

简而言之,它保留其参数的值类别.完美的转发可以确保将提供给函数的参数转发给具有与引用崩溃可能已经发生(涉及通用/转发参考).

In a nutshell, it preserves the value category of its argument. Perfect forwarding is there to ensure that the argument provided to a function is forwarded to another function (or used within the function) with the same value category (basically r-value vs. l-value) as originally provided. It is typically used with template functions where reference collapsing may have taken place (involving universal/forwarding references).

请考虑以下代码示例.删除 std :: forward 将打印出需要左值,并添加 std :: forward 打印出需要右值. func 根据是右值还是左值而被重载.在没有 std :: forward 的情况下调用它会导致错误的重载.在这种情况下,需要使用 std :: forward ,因为使用右值调用 pass .

Consider the code sample below. Removing the std::forward would print out requires lvalue and adding the std::forward prints out requires rvalue. The func is overloaded based on whether it is an rvalue or an lvalue. Calling it without the std::forward calls the incorrect overload. The std::forward is required in this case as pass is called with an rvalue.

#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;
}

这篇关于为什么要使用std :: forward?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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