std :: move和std :: forward有什么区别?

我看到这里: 移动构造函数调用基类移动构造

有人可以解释:

  1. std::movestd::forward之间的区别,最好用一些代码示例?
  2. 如何轻松考虑,何时使用哪个

std::move需要一个对象,并允许你把它当作一个临时值(一个右值)。 虽然它不是一个语义要求,但通常接受对右值的引用的函数将使其无效。 当你看到std::move ,它表示不应该在之后使用对象的值,但是你仍然可以分配一个新值并继续使用它。

std::forward有一个用例:将一个模板函数参数(在函数内部)转换为调用者用来传递它的值类别(左值或右值)。 这允许右值参数作为右值传递,左值作为左值传递,称为“完美转发”。

为了说明 :

 void overloaded( int const &arg ) { std::cout << "by lvalue\n"; } void overloaded( int && arg ) { std::cout << "by rvalue\n"; } template< typename t > /* "t &&" with "t" being template param is special, and adjusts "t" to be (for example) "int &" or non-ref "int" so std::forward knows what to do. */ void forwarding( t && arg ) { std::cout << "via std::forward: "; overloaded( std::forward< t >( arg ) ); std::cout << "via std::move: "; overloaded( std::move( arg ) ); // conceptually this would invalidate arg std::cout << "by simple passing: "; overloaded( arg ); } int main() { std::cout << "initial caller passes rvalue:\n"; forwarding( 5 ); std::cout << "initial caller passes lvalue:\n"; int x = 5; forwarding( x ); } 

正如霍华德所提到的那样,这两个function都只是简单地引用到引用types中,也有相似之处。 但是,除了这些特定的用例(其中包括右值引用强制types的99.9%的用处)之外,您应该直接使用static_cast并且写出一个很好的解释。

std::forwardstd::move都是强制转换。

 X x; std::move(x); 

上面将typesX的左值expression式x转换为typesX的右值expression式(一个x值是精确的)。 move也可以接受一个右值:

 std::move(make_X()); 

在这种情况下它是一个标识函数:使用Xtypes的右值并返回typesX的右值。

std::forward可以在一定程度上select目的地:

 X x; std::forward<Y>(x); 

将typesX的左值expression式x为types为Y的expression式。对于Y可以有什么约束。

Y可以是X的可访问的Base,或者是对X的Base的引用.Y可以是X,或者是对X的引用。不能用cv-qualifiers forward ,但是可以添加cv-qualifiers。 Y不能是只能从X转换的types,除非通过可访问的Base转换。

如果Y是一个左值引用,结果将是一个左值expression式。 如果Y不是一个左值引用,结果将是一个右值(xvalue是精确的)expression式。

只有当Y不是左值引用时, forward才能取右值。 也就是说,你不能左值左值。 这是出于安全原因,因为这样做通常会导致悬挂引用。 但是将右值赋给右值是可以的。

如果尝试将Y指定为不允许的内容,则会在编译时捕获该错误,而不是在运行时捕获。

std::forward用来传递一个参数,就像传递给一个函数一样。 就像这里显示的那样:

何时使用std :: forward来转发参数?

使用std::move提供一个对象作为右值,可能匹配移动构造函数或接受右值的函数。 它为std::move(x)即使x本身不是右值。