我总是读到std::forward
仅适用于模板参数。然而,我问自己为什么。请参见以下示例:
void ImageView::setImage(const Image& image){
_image = image;
}
void ImageView::setImage(Image&& image){
_image = std::move(image);
}
这两个函数的作用基本相同;一个采用左值参考,另一个采用右值参考。现在,我想自从std::forward
如果参数是左值引用,则应该返回左值引用;如果参数是 1,则应该返回右值引用,此代码可以简化为如下所示:
void ImageView::setImage(Image&& image){
_image = std::forward(image);
}
这有点类似于 cplusplus.com 提到的示例std::forward
(只是没有任何模板参数)。我只是想知道这是否正确,如果不正确,原因是什么。
我也在问自己到底有什么区别
void ImageView::setImage(Image& image){
_image = std::forward(image);
}
You cannot use std::forward
没有明确指定其模板参数。它是有意在非推导的上下文中使用的。
要理解这一点,您需要真正理解如何转发引用(T&&
对于推导的T
)在内部工作,而不是因为“这很神奇”而挥手而走。那么让我们看看这个。
template <class T>
void foo(T &&t)
{
bar(std::forward<T>(t));
}
假设我们打电话foo
像这样:
foo(42);
-
42
是类型的右值int
.
-
T
推导为int
.
- 致电给
bar
因此使用int
作为模板参数std::forward
.
- 返回类型为
std::forward<U>
is U &&
(在这种情况下,那就是int &&
) so t
作为右值转发。
现在,我们打电话foo
像这样:
int i = 42;
foo(i);
-
i
是类型的左值int
.
- 由于完美转发的特殊规则,当类型的左值
V
用于推导T
在类型参数中T &&
, V &
用于扣除。因此,在我们的例子中,T
推论为int &
.
因此,我们指定int &
作为模板参数std::forward
。因此它的返回类型将是“int & &&
”,折叠为int &
。这是一个左值,所以i
作为左值转发。
Summary
为什么这适用于模板是当你这样做时std::forward<T>
, T
有时是引用(当原始值是左值时),有时不是引用(当原始值是右值时)。std::forward
因此将根据需要转换为左值或右值引用。
您无法在非模板版本中执行此操作,因为您只有一种类型可用。更不用说这样的事实setImage(Image&& image)
根本不接受左值——左值不能绑定到右值引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)