Forward or Move

好久不见. 提交于 2019-12-25 04:14:54

问题


Are these valid usage of move and forward?
Are f3 and f4 the same?
Is it dangerous to do so?
Thank you!

#include <utility>
class A {};
A f1() {
  A a;
  return a;   // Move constructor is called
}
A f2(A&& a) {
  return a;   // Copy constructor is called, which is what I try to avoid.
}
A f3(A&& a) {
  return std::forward<A&&>(a); // Move constructor is called
}
A f4(A&& a) {
  return std::move(a); // Move constructor is called
}

回答1:


  • Use std::forward with a universal reference, i.e. a template <typename T> ... T&&.

  • Use std::move with an rvalue reference (like your A&&).

So both f1 and f4 are plausible solutions. They do different things, so you have to decide which one you want.

Do not use f2 or f3.




回答2:


std::forward exists because of a quirk in how && works under type deduction.

Under type deduction, the T in T&& will bind to one of 3 possibilities. If being deduced from an lvalue int&, T will bind to int&. Then int& && is just a int&. If being deduced from an lvalue int const&, T will bind to int const&, and int const& && is int const&. If being deduced from an rvalue int of some kind, T will bind to int, and int&& is int&&.

std::forward is a utility function to reverse that map. The three pertinent signatures of std::forward<> are: T& std::forward<T&>(T&) or T const& std::forward<T const&>(T const&) or T&& std::forward<T>(T&&)

All of this ends up being exceedingly useful when doing the technique known as "perfect forwarding", where you use T&&t in a type deduction context, then std::forward<T>(t) to pass on the "same type" as was deduced from to another call.

Note that there are a few simplifying lies above. There are is also the possibility of T const&& which is pretty obscure type-wise, as an example. I probably glossed over some details of how the type deduction works, and the terms rvalue and lvalue don't fully reflect the full 5-fold (or is it 6?) different kinds of variable values in C++11.




回答3:


For your example, they will do the same thing, but it is idiomatic to use std::move

A f(A&& a) {
  // use std::move(a)
}

A slightly different case is with function templates

template<typename A>
A f(A&& a) {
   // use std::forward<A>(a)
}

The difference is that the second version can receive both lvalues and rvalues (Scott Meyers named them "universal references"), whereas the first version can only receive rvalues.



来源:https://stackoverflow.com/questions/16014481/forward-or-move

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!