我一直在观看 Scott Meyers在 C++ 和 Beyond 2012 会议上关于通用引用的演讲,到目前为止一切都很有意义。然而,一位观众在大约 50 分钟时提出了一个我也想知道的问题。迈耶斯说他不关心答案,因为它是非惯用的并且会让他的头脑变得愚蠢,但我仍然感兴趣。
呈现的代码如下:
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
关键是当我们采用右值引用时,我们知道我们有一个右值,所以我们应该std::move
保留它是一个右值的事实。当我们采用通用引用(T&&
,其中T
是推导类型)时,我们希望std::forward
保留它可能是左值或右值的事实。
所以问题是:既然std::forward
保留了传递给函数的值是左值还是右值,并且std::move
只是将其参数转换为右值,我们可以std::forward
在任何地方使用吗?在我们使用 的所有情况下都会std::forward
表现得像,还是迈耶斯的概括遗漏了一些重要的行为差异?std::move
std::move
我并不是建议任何人都应该这样做,因为正如 Meyers 正确所说,它完全不是惯用的,但以下也是 的有效用法std::move
:
void doWork(Widget&& param) // move
{
// ops and exprs using std::forward<Widget>(param)
}