C++11新特性之 std::forward(完美转发)(转)

我们也要时刻清醒,有时候右值会转为左值,左值会转为右值。 
(也许“转换”二字用的不是很准确)

如果我们要避免这种转换呢? 
我们需要一种方法能按照参数原来的类型转发到另一个函数中,这才完美,我们称之为完美转发。

std::forward就可以保存参数的左值或右值特性。

因为是这样描述的: 
When used according to the following recipe in a function template, forwards the argument to another function with the value category it had when passed to the calling function.

例子:

1 template<class T>
2 void wrapper(T&& arg) 
3 {
4     foo(std::forward<T>(arg)); // Forward a single argument.
5 }

 

If a call to wrapper() passes an rvalue std::string, then T is deduced to std::string (not std::string&, const std::string&, or std::string&&), and std::forward ensures that an rvalue reference is passed to foo. 
If a call to wrapper() passes a const lvalue std::string, then T is deduced to const std::string&, and std::forward ensures that a const lvalue reference is passed to foo. 
If a call to wrapper() passes a non-const lvalue std::string, then T is deduced to std::string&, and std::forward ensures that a non-const lvalue reference is passed to foo.

看一段网站上的代码(http://en.cppreference.com/w/cpp/utility/forward):

 1 #include <iostream>
 2 #include <memory>
 3 #include <utility>
 4 #include <array>
 5 
 6 struct A {
 7     A(int&& n) { std::cout << "rvalue overload, n=" << n << "\n"; }
 8     A(int& n)  { std::cout << "lvalue overload, n=" << n << "\n"; }
 9 };
10 
11 class B {
12 public:
13     template<class T1, class T2, class T3>
14     B(T1&& t1, T2&& t2, T3&& t3) :
15         a1_{std::forward<T1>(t1)},
16         a2_{std::forward<T2>(t2)},
17         a3_{std::forward<T3>(t3)}
18     {
19     }
20 
21 private:
22     A a1_, a2_, a3_;
23 };
24 
25 template<class T, class U>
26 std::unique_ptr<T> make_unique1(U&& u)
27 {
28     return std::unique_ptr<T>(new T(std::forward<U>(u)));
29 }
30 
31 template<class T, class... U>
32 std::unique_ptr<T> make_unique(U&&... u)
33 {
34     return std::unique_ptr<T>(new T(std::forward<U>(u)...));
35 }
36 
37 int main()
38 {   
39     auto p1 = make_unique1<A>(2); // rvalue
40     int i = 1;
41     auto p2 = make_unique1<A>(i); // lvalue
42 
43     std::cout << "B\n";
44     auto t = make_unique<B>(2, i, 3);
45 }
46 //输出:
47 rvalue overload, n=2
48 lvalue overload, n=1
49 B
50 rvalue overload, n=2
51 lvalue overload, n=1
52 rvalue overload, n=3

最后,记住: 
不管是T&&、左值引用、右值引用,std::forward都会按照原来的类型完美转发。

 

转自:https://blog.csdn.net/wangshubo1989/article/details/50485951

posted @ 2018-05-23 18:27  鸭子船长  阅读(350)  评论(0编辑  收藏  举报