0

这些是移动和前进的有效用法吗?
f3 和 f4 是一样的吗?
这样做有危险吗?
谢谢!

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

3 回答 3

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.

于 2013-04-15T14:30:16.713 回答
2
  • std::forward通用参考一起使用,即 a template <typename T> ... T&&

  • std::move右值引用一起使用(如您的A&&)。

所以两者f1都是f4合理的解决方案。他们做不同的事情,所以你必须决定你想要哪一个。

不要使用f2f3

于 2013-04-15T11:55:10.353 回答
1

对于您的示例,他们会做同样的事情,但使用它是惯用的std::move

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

函数模板的情况略有不同

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

不同之处在于第二个版本可以同时接收左值和右值(Scott Meyers 将它们命名为“通用引用”),而第一个版本只能接收右值。

于 2013-04-15T11:58:28.820 回答