5

据我从这个解释如何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在于定义方式(使用&&

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

4

1 回答 1

5

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

在右值引用重载中进行关键错误检查;这是一个健全性检查,以确保std::forward在提供右值时不会调用它来转发到左值引用;基本上确保代码std::forward<int&>(42);无法编译。std::forward旨在用于公式std::forward<T>where Tis from the deduced contextT&&参考中所述。重载影响与带有所需错误检查的条件返回相同的结果。

的实现std::forward面向 Scott Meyers 在他的Going Native 2013演讲中谈到的“条件转换”。Scott Meyers 在他的演讲中给出了以下伪代码来解释std::forward(大约 20 分钟)的工作原理;

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&&
  }
}

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


TL;DR 为什么需要它?基本上; 它可以防止错误使用std::forward(例如悬空引用、对不再可用的临时对象的引用、修改/修改的文字等)。

于 2014-08-05T10:55:36.847 回答