简体   繁体   English

std::forward 和有什么区别<T> () 和 std::move 完美转发右值引用时?

[英]What is the difference between std::forward<T>() and std::move when perfectly forwarding rvalue references?

I was wondering what the difference is (if there is one) between using std::move() and using std::forward() in the below code sample:我想知道在下面的代码示例中使用 std::move() 和使用 std::forward() 之间有什么区别(如果有的话):

struct Foo {};

class Bar {

private:
  std::vector<Foo> storage;

public:

  template<typename T>
  void add(T&& t) {

     constexpr auto isFoo = std::is_same_v<std::decay_t<T>,Foo>;
     
     static_assert(isFoo,"Attempting to push non-Foo type to vector");
     
     if constexpr(isFoo){
         
        storage.push_back(std::forward<T>(t));
     }
  }
};


class BarProxy {

private:
  Bar &bar;

public:
  BarProxy(Bar &bar) : bar{bar} {}

  void add(const Foo &foo) {

     bar.add(foo);
  }

  void add(Foo &&foo) {
    
     bar.add(std::move(foo));
     //bar.add(std::forward<Foo>(foo)); is there a difference between using this and std::move(foo)?
  }
};

int main() {

    Bar bar = Bar{};
    BarProxy proxy = BarProxy(bar);

    proxy.add(Foo{});

    return 0;
}

Is there a difference between using std::forward and std::move in add(Foo &&foo) method?在 add(Foo &&foo) 方法中使用 std::forward 和 std::move 有区别吗?

This is the TLDR of what std::forward is for:这是std::forward的 TLDR:

template <class T>
void f1(T&& foo) {
   ...
}

template <class T>
void f2(T&& bar) {
   ...
   f1(bar);
   ...
}

...

f2(/*see explanation*/);

You could say that f2 forwards its argument to f1 .您可以说f2其参数转发给f1 So depending on what you replace the comment with, and depending on what exactly f1 needs to do with its data, you might end up in a situation where you'd need two overrides like因此,根据您替换评论的内容以及f1需要对其数据执行的操作,您最终可能会遇到需要两个覆盖的情况,例如

template <class T>
void f1(const T& foo) {...}

template <class T>
void f1(T& foo) {...}

This is an... okay solution if you only have one parameter.如果您只有一个参数,这是一个……好的解决方案。 But if f1 takes two parameters, then you need four overrides to handle all combinations, if it takes three parameters, you need nine overrides, etc. You can see that this quickly becomes untenable when you add arguments.但是如果f1有两个参数,那么你需要四个覆盖来处理所有的组合,如果它需要三个参数,你需要九个覆盖,等等。你可以看到,当你添加参数时,这很快就变得站不住脚了。 This is where forward comes in. Here's the original example with forward :这就是forward的用武之地。这是forward的原始示例:

template <class T>
void f1(T&& foo) {
   ...
}

template <class T>
void f2(T&& bar) {
   ...
   f1(std::forward(bar));
   ...
}

Now, you don't have the problem I described earlier.现在,您没有我之前描述的问题。 Here's a more in-depth explanation that goes into how and why this works, along with an explainer of C++11's concept of "universal references" 这是一个更深入的解释,介绍了它的工作原理和原因,以及 C++11 的“通用引用”概念的解释器

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

相关问题 std::move 和 std::forward 有什么区别 - What's the difference between std::move and std::forward 类中的 std::forward 和 rvalue 引用 - std::forward and rvalue references in a class 使用转发引用时,std :: move是否需要与std :: forward结合使用? - Does std::move need to be combined with std::forward when using forwarding references? std::move() 和 std::add_rvalue_reference() 之间的区别 - Difference between std::move() and std::add_rvalue_reference() 普通右值引用和std :: forward返回的引用之间有什么区别? - What's the difference between an ordinary rvalue reference and one returned by std::forward? 当我们使用右值引用时,究竟会发生什么?std :: move如何工作? - What exactly happens when we use rvalue references and how does std::move work? 是std :: forward之间的任何区别 <T> 和std :: forward <decltype(t)> ? - is any difference between std::forward<T> and std::forward<decltype(t)>? 为什么在使用转发引用时需要 std::forward? - Why is std::forward needed when using forwarding references? 静态转换到右值引用和 std::move 之间有什么区别吗 - is there any difference between static cast to rvalue reference and std::move 完美转发`decltype(std :: forward <Args>(args))...`和Args &&之间的区别是什么? - In perfect forwarding what is the difference between `decltype(std::forward<Args>(args))…` and Args&&
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM