C++ 11`T &&`参数丢失了`&&'正确的术语?

And*_*zos 5 c++ c++11

以下C++ 11代码无法编译:

struct T {};

void f(T&&) { }

void g(T&& t) { f(t); }

int main()
{
    g(T());
}
Run Code Online (Sandbox Code Playgroud)

正确的方法是:

void g(T&& t) { f(move(t)); }
Run Code Online (Sandbox Code Playgroud)

这很难用正确的自然语言术语来解释.该参数t似乎失去了它需要恢复的"&&"状态std::move.

你叫什么的T()g(T())

你叫什么的T&&g(T&& t)

你叫什么的tg(T&& t)

你叫什么的tf(t)f(move(t))

你怎么称呼返回值move(t)

你怎么称呼整体效果?

该标准的哪个部分处理此问题?

fre*_*low 7

所有参数都是左值,即使它们的类型是"右值参考".它们有名称,因此您可以根据需要随时查看它们.如果命名的右值引用是rvalues,那么你会得到令人惊讶的行为.我们不希望从左值的隐式移动,这就是你必须明确写的原因std::move.


Jon*_*ely 7

关键点在于参数T&& b只能绑定到右值,但是稍后引用时表达式b是左值.

所以函数的参数必须是一个rvalue,但是在函数体内,参数是一个左值,因为那时你已经绑定了一个引用并给它一个名字,它不再是一个未命名的临时值.

表达式具有类型(例如int,string等等)并且它具有值类别(例如,左值或右值),并且这两个事物是不同的.

一个命名变量,声明为T&& b具有"rvalue reference to T" 类型,并且只能绑定到rvalue,但是当您稍后使用该引用时,该表达式b具有值类别"lvalue",因为它具有名称并引用某个对象(无论引用是什么,即使这是一个右值.)这意味着传递b给另一个带rvalue的函数,你不能只说f(b)因为b是左值,所以你必须将它(后)转换为rvalue,通过std::move(b).


gus*_*f r 5

你在g(T())中称之为T()?

临时的(可移动的).

你怎么称待T && in g(T && t)?

T &&是一个r值引用,表示可以移动的对象.

你怎么称呼t(g&t)?

t实际上是一个l值,因为你可以通过名字来引用它.

你在f(t)和f(move(t))中称为t?

  1. L值
  2. 当move()返回时,l值被转换为r值引用

你怎么称为move(t)的返回值?

r值参考

作为一个笔记; 你应该调用结构C,并写一个单独的例子,其中T实际上是寺庙化的.该代码需要不同的话,因为在一个函数template< typename T > void f( T&& t );,你不能简单地使用std::move()而不被非常小心,因为T实际上可以是一个const&,在这种情况下,你不能使用std::move(),而是使用完美转发std::forward< T >( t )