小编典典

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

all

有人可以解释一下:

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

阅读 84

收藏
2022-08-01

共1个答案

小编典典

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 );
}

正如霍华德所提到的,这两个函数也有相似之处,因为这两个函数都只是转换为引用类型。但在这些特定用例(涵盖 99.9%
的右值引用强制转换的有用性)之外,您应该static_cast直接使用并为您正在做的事情写一个很好的解释。

2022-08-01