std::move和std::forward仅仅是执行转换(cast)的函数(事实上是函数模板)。std::move无条件的将它的实参转换为右值,而std::forward只在特定情况满足时下进行转换。
std::move
template <class _Ty>
constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept {
return static_cast<remove_reference_t<_Ty>&&>(_Arg);
}
std::move函数模板返回一个remove_reference_t<_Ty>&&,确保返回的一定是右值。
std::forward
template <class _Ty>
constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept {
return static_cast<_Ty&&>(_Arg);
}
template <class _Ty>
constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept {
static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
return static_cast<_Ty&&>(_Arg);
}
std::forward函数模板使用时显示指明模板参数类型,根据条件进行类型转换。
std::forward完美转发
void process(Widget& lval) {
std::cout << "左值process" << std::endl;
}
void process(Widget&& lval) {
std::cout << "右值process" << std::endl;
}
template<typename T>
void logAndProcess(T&& param) {
process(temp::forward<T>(param));
}
Widget w;
logAndProcess(w);
logAndProcess(Widget());
logAndProcess模板函数,使用通用引用的形式进行模板类型推导,如果传入左值,T
和Param
都会被推导为左值引用;如果传入右值,就正常推导,即T推导为Widget,param推导为Widget&&。
所以logAndProcess(w)函数体中,T为Widget&,param为Widget&,forward
logAndProcess(Widget())函数体中,T为Widget,param为Widget&&,forward
std::forward(w) 和 std:forward<Widget&>(w)
std::forward