试图了解使用变量是否std::forward
是auto&&
传递这些变量以允许移动的正确方法。
假设有一个函数:
void moveWidget(Widget&& w);
和调用者 - 两个变量来引用右值和左值:
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
is rvalue和uniRefLV
is lvalue但从概念上讲,它们都是通用引用,如果定义不同,它们可以表示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
?我们应该使用三个选项中的哪一个来实现完美转发?