为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
繁花不似锦 2019-10-15 09:29:06
我在这里看到了这一点: Move构造函数调用基类Move构造函数有人可以解释:之间的差std::move和std::forward,优选用一些代码示例?如何轻松思考,以及何时使用
查看完整描述

3 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

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

}

正如霍华德(Howard)所提到的,这两个函数也都具有相似之处,因为它们只是转换为引用类型。但是,除了这些特定的用例(覆盖了右值引用强制转换的99.9%的有用性)之外,您应该static_cast直接使用并为自己的工作写一个很好的解释。


查看完整回答
反对 回复 2019-10-15
?
catspeake

TA贡献1111条经验 获得超0个赞

两者std::forward和std::move都不过是演员。


X x;

std::move(x);

上面的方法将x类型X 的左值表达式转换为类型X的右值表达式(确切地说是x值)。  move也可以接受右值:


std::move(make_X());

在这种情况下,它是一个标识函数:采用类型X的右值并返回类型X的右值。


随着std::forward您可以选择目标在一定程度上:


X x;

std::forward<Y>(x);

将x类型X 的左值表达式转换为类型Y的表达式。对Y的限制。


Y可以是X的可访问底数,也可以是X的底数的引用。Y可以是X或对X的引用。一个不能使用放弃cv限定词forward,但可以添加cv限定词。Y不能是只能从X转换的类型,除非通过可访问的Base转换。


如果Y是左值引用,则结果将是左值表达式。如果Y不是左值引用,则结果将是右值(精确地说是xvalue)表达式。


forward仅当Y不是左值引用时才可以使用右值参数。也就是说,您不能将右值转换为左值。出于安全原因,因为这样做通常会导致悬挂参考。但是将右值转换为右值是可以的并且可以的。


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


查看完整回答
反对 回复 2019-10-15
?
GCT1015

TA贡献1827条经验 获得超4个赞

std::forward用于完全按照传递给函数的方式转发参数。就像这里显示的那样:


什么时候使用std :: forward转发参数?


使用std::move提供对象作为右值,以匹配移动构造函数或接受右值的函数。std::move(x)即使它x本身不是右值,它也会这样做。


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 1536 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信