我看到这个在这里的std ::移动和性病的区别: Move Constructor calling base-class Move Constructor什么::向前
有人能解释一下:
std::move
和std::forward
之间的区别,最好用一些代码的例子吗?- 如何去想它很容易,当要使用的
我看到这个在这里的std ::移动和性病的区别: Move Constructor calling base-class Move Constructor什么::向前
有人能解释一下:
std::move
和std::forward
之间的区别,最好用一些代码的例子吗?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
,写的你在做什么了很好的解释。
我不确定'std :: forward'的_only_用例是函数参数的完美转发。我遇到了想要完美转发其他内容的情况,例如对象成员。 – 2013-12-11 16:53:44
@GeoffRomer参数的成员?你有一个例子吗? – Potatoswatter 2013-12-11 23:11:51
我张贴的例子作为一个单独的问题:http://stackoverflow.com/questions/20616958/stdforward-without-perfect-forwarding – 2013-12-16 23:47:51
std::forward
用于向前参数正是它被传递给函数的方式。就像这里显示:
When to use std::forward to forward arguments?
使用std::move
提供了一个对象作为右值,以匹配可能一招构造或接受右值的函数。即使x
本身不是一个右值,它也可以用于std::move(x)
。
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的引用。不能用forward
来抛弃cv限定符,但可以添加cv-预选赛。 Y不能是只能从X转换的类型,除非通过可访问的Base转换。
如果Y是一个左值引用,则结果将是一个左值表达式。如果Y不是左值引用,结果将是一个右值(xvalue是精确的)表达式。
forward
只有当Y不是左值引用时才能取右值参数。也就是说,你不能左值左值。这是出于安全原因,因为这样做通常会导致悬挂引用。但是将右值赋给右值是可以的,并且是允许的。
如果您尝试将Y指定为不允许的内容,则错误将在编译时捕获,而不是在运行时捕获。
如果我完美地使用'std :: forward'将一个对象转发给函数,那么在该函数执行后,我可以使用该对象吗?我知道,在std :: move的情况下,这是一个未定义的行为。 – iammilind 2017-12-26 11:32:49
关于'move':https://stackoverflow.com/a/7028318/576911对于'forward',如果你在一个左值传递,你的API应该如果它收到一个左值反应。通常这意味着该值将不被修改。但是,如果它是非常量左值,那么您的API可能已经对其进行了修改。如果你传入一个右值,这通常意味着你的API可能已经从它移出,并且因此将应用https://stackoverflow.com/a/7028318/576911。 – 2017-12-26 15:29:54
也看到这两个相关的问题:我应该使用std ::移动或std中移动构建函数/赋值运算符::前锋?](http://stackoverflow.com/q/8860233/500104)和[如何std :: forward work?](http://stackoverflow.com/q/8526598/500104)(以及重复的问题)。 – Xeo 2012-03-12 17:34:44
“如何轻松地考虑它,以及何时使用”当你想要*移动*值时使用'移动',当你想使用完美的转发时使用'前进'。这里不是火箭科学;) – 2012-03-12 17:47:02
move()执行无条件转换,其中forward()根据传递的参数执行转换。 – 2016-05-18 12:24:43