【发布时间】:2016-03-25 22:05:01
【问题描述】:
std::move 和std::forward 之间的区别众所周知,我们使用后者来保留转发对象的值类别,而前者用于强制转换为右值引用以启用移动语义。
在有效的现代 C++ 中,存在一条说明
在右值引用上使用
std::move,在通用引用上使用std::forward。
但在以下场景中(以及我们不想更改值类别的场景),
template <class T>
void f(vector<T>&& a)
{
some_func(std::move(a));
}
其中a不是转发引用而是简单的右值引用,那么做下面不就完全一样了吗?
template <class T>
void f(vector<T>&& a)
{
some_func(std::forward<decltype(a)>(a));
}
由于这可以很容易地封装在这样的宏中,
#define FWD(arg) std::forward<decltype(arg)>(arg)
总是这样使用这个宏定义不是很方便吗?
void f(vector<T>&& a)
{
some_func(FWD(a));
}
这两种写法不是完全等价的吗?
【问题讨论】:
-
我无法将宏解决方案视为比写
move()... 更方便...但这让我觉得这是一个基于意见的问题。两者都做同样的事情 -
但有时参数是常规引用,您确实想移动向量。继续使用转发并不能做到这一点
-
@Barry 我想确认它们是等价的,谢谢。我不同意他们是否基于意见,仅仅倡导一种编程风格并不意味着偏见,一个人可能有很好的理由这样做(并且能够详细说明)
-
添加宏会混淆理解。如果你故意做一些奇怪的事情,就像你在这里做的那样,它应该是显而易见的,即使是以冗长为代价。
-
关于“……做这个会不会完全一样……”我觉得完全一样;因为 vector
&& a 是一个右值引用,并且对右值引用进行无条件强制转换(移动)或有条件强制转换(转发)没有区别。