为什么我们需要第二个std :: forward专业化?

时间:2014-08-05 08:05:07

标签: c++ c++11 perfect-forwarding

据我对std::forward的工作原理的解释http://thbecker.net/articles/rvalue_references/section_08.html我可以理解,我们只能免除std::forward的一个版本:

template<class S>
S&& forward(typename remove_reference<S>::type& a) noexcept

但实际上,我们有(http://en.cppreference.com/w/cpp/utility/forward)第二版:

template< class T >
T&& forward( typename std::remove_reference<T>::type&& t );

与前一个版本的不同之处仅在于如何定义t(使用&&

那么,为什么我们需要呢?如果删除它会破坏什么?

1 个答案:

答案 0 :(得分:4)

std::forward重载的参数(使用std::remove_reference)删除了原本会发生的任何引用折叠和参数推导,并强制将左值和右值引用绑定到正确的重载。这也是在不添加或删除原始参数const的一部分(或不是其中一部分)的任何可能T的情况下完成的(即我们不使用const T&,因为它实质上是constT&&没有的右值添加std::forward,但它们都可以绑定到相同的右值。)

在右值参考重载中 键错误检查已完成 ;这是一个完整性检查,以确保在提供右值时不调用std::forward<int&>(42);转发给左值引用;基本上确保像std::forward这样的代码无法编译。 std::forward<T>旨在用于公式T,其中T&&来自推导的上下文std::forward,如reference中所述。重载会产生与带有所需错误检查的条件返回相同的结果。

std::forward的实施适用于&#34;条件演员&#34; Scott Meyers在他的Going Native 2013演讲中谈到了这一点。 Scott Meyers在他的演讲中给出了以下伪代码来解释template <typename T> T&& forward(T&& param) { // T&& here is formulated to disallow type deduction if (is_lvalue_reference<T>::value) { return param; // return type T&& collapses to T& in this case } else { return move(param); // return type is T&& } } 的运作(大约在20分钟左右);

std::forward

std::move实现为在其参数类型为左值时返回左值引用,如果其参数类型为右值,则返回右值引用(等效于std::forward)。 / p>


TL; DR 为什么需要?基本上;它可以防止{{1}}的错误使用(例如悬空引用,不再提供临时引用,修改/修改文字等)。