试图了解是否使用std::forward与auto&&变量是通过这些变量,允许移动的正确途径.
假设有一个功能:
void moveWidget(Widget&& w);
和调用者 - 两个变量来引用rvalue和lvalue:
Widget w;
auto&& uniRefLV = w;            // lvalue initialiser, 
                                // uniRefLV's type is Widget&
auto&& uniRefRV = std::move(w); // rvalue initialiser, 
                                // uniRefRV's type is Widget&&
我们知道类型的变量auto&&是通用引用,因为存在类型推导.这意味着双方uniRefRV并uniRefLV都普遍引用.
在我的例子中,显然uniRefRV是rvalue并且uniRefLV是左值,但从概念上讲它们都是通用引用,如果定义不同,它们可以表示rvalue或lvalue.
现在,我想调用moveWidget()并完善这些通用引用类型.该指南(由Scott Meyers撰写)说:
传递和返回右值引用通过
std::move,普遍引用通过std::forward.
除非我完全误解了指南,否则使用起来似乎合乎逻辑std::forward.但是让我们考虑所有可能的选择:
// (1) std::move:
moveWidget(std::move(uniRefLV)); // Compiles and looks fine
                                 // but violates the guideline?
                                 // (unconditionally casts lvalue to rvalue)
moveWidget(std::move(uniRefRV)); // Same as above - but not an issue here
                                 // as we cast rvalue to rvalue
// (2) std::forward with Widget:
moveWidget(std::forward<Widget>(uniRefLV)); // Compiles, follows the guideline
                                            // but doesn't look right - what if
                                            // we didn't know Widget's type?
moveWidget(std::forward<Widget>(uniRefRV)); // Same as above
// (3) std::forward with decltype:
moveWidget(std::forward<decltype(uniRefLV)>(uniRefLV)); // Fails to compile! (VC10)
                                                        // follows the guideline
                                                        // has nice and short syntax :)
moveWidget(std::forward<decltype(uniRefRV)>(uniRefRV)); // Compiles fine
你认为我们应该把两个引用uniRefLV和uniRefRV平等,我们应该使用哪三个选项完美转发?
R. *_*des 11
你误解了指南.或者至少从字面上看它.
我认为这里有三个重要的事情需要实现.
首先,这里所有类型都是已知的.对于通用引用的建议主要适用于具有模板的通用代码,如果某些内容是或者采用左值引用或右值引用,则根本不知道.
其次,该函数采用右值引用:您必须传递右值.期.这里别无选择.
而符合逻辑的结论是,你并不想传递一个普遍的参考:无论你传递必须是一个右值,它永远是一个左值.通用引用可以是左值(如果它们被实例化为左值引用).传递一个通用引用意味着"我不知道这是什么样的引用,我可以将它作为rvalue或左值传递,所以我正在传递它,就像我得到它一样".这个问题的情况更像是"我确切地知道我必须通过什么,所以这就是我将要通过的".
让我们假设这种情况并不像看起来那样简单。而不是giveMeInt像这样:
template <typename T>
typename complex_computation<T>::type giveMeSomething(T t);
取而代之的是moveMe,您实际上拥有一个通用的参考,因此不需要无条件的参考std::move。
template <typename T>
void wantForwarded(T&&);
现在,您实际上需要完美的转发。
auto&& uniRef = giveMeSomething(iDontKnowTheTypeOfThis);
wantForwarded(std::forward<decltype(uniRef)>(uniRef);
| 归档时间: | 
 | 
| 查看次数: | 1136 次 | 
| 最近记录: |