为什么右值引用变量不是右值? [英] Why are rvalues references variables not rvalue?
问题描述
假设我有两个函数 f
的重载。 f(T&)
和 f(T&)
。
然后在 g
的正文中:
g(T& t){f(t);}
将调用重载 f(T&)
,因为t被视为左值。
Let's say I have two overloads of a function f
. f(T&&)
and f(T&)
.
Then in the body of g
:
g(T&& t) { f(t);}
the overload f(T&)
will be called because t is considered an lvalue.
这对我来说非常令人惊讶。签名为 f(T&)
的函数如何不匹配类型为 T&
的调用?
更让我惊讶的是,呼叫 f(static_cast< T&>(t))
实际上会调用右值过载 f(T&)
。
This is very surprising to me. How a function with signature f(T&&)
can not match a call with type T&&
?
What suprises me even more is that a call f(static_cast<T&&>(t))
would actually call the rvalue overload f(T&&)
.
哪些C ++规则使之成为可能? T&
不仅仅是一种类型吗?
What are the C++ rules that make this possible? Is T&&
more than a type?
推荐答案
被自动视为右值的是没有名称的事物,并且(很快)没有名称的事物(在返回值的情况下)。
The things that are automatically treated as rvalues are things without names, and things that (very shortly) will not have a name (in the return value case).
T&& t
有一个名字,它是 t
。
右值是那些事情是,在之后指代它们的使用点几乎是不可能的。
The reason why rvalues are those things is that referring to them after that point of use is next to impossible.
T&&
是类型右值引用。右值引用只能绑定到右值(不涉及 static_cast
),但是否则它是右值引用类型的左值。
T&&
is the type rvalue reference. An rvalue reference can only bind to an rvalue (without a static_cast
being involved), but it is otherwise an lvalue of type rvalue reference.
它是右值引用类型的事实仅在其构造过程中起作用,如果执行 decltype(variable_name)
也是如此。否则,它只是引用类型的另一个左值。
The fact it is of type rvalue reference only matters during its construction, and if you do decltype(variable_name)
. It is otherwise just another lvalue of reference type.
std :: move(t)
进行返回static_cast< T&>(t);
并返回右值引用。
std::move(t)
does a return static_cast<T&&>(t);
and returns an rvalue reference.
支配此规则的规则以C ++标准中的标准语言编写。复制/粘贴它们并没有什么用处,因为它们不那么容易理解。
The rules that govern this are written in standardese in the C++ standard. A copy/paste of them won't be all that useful, because they are not that easy to understand.
第一个一般规则是,您会隐式地采取行动(又名,绑定到右值引用参数的参数),当您从函数返回命名值时,或者当值没有名称时,或者函数显式返回右值引用时。
The first general rule is, you get an implicit move (aka, parameter that binds to an rvalue reference argument) when you return a named value from a function, or when a value has no name, or when a function explicitly returns an rvalue reference.
第二,只有右值引用和 const&
可以绑定到右值。
Second, that only rvalue references and const&
can bind to rvalues.
第三条引用生存期直接绑定到构造函数外部的引用时,将发生临时值扩展。 (因为只有右值引用和 const&
可以直接绑定到临时目录,所以这仅适用于它们)
Third, reference lifetime extension on temporary values occurs when directly bound to a reference outside of a constructor. (as only rvalue references and const&
can directly bind to a temporary, this only applies to them)
Forth , T&
并不总是右值引用。如果 T
的类型为 X&
或 X const&
,然后引用折叠将 T&
转换为 X&
或 X const&
。
Forth, T&&
isn't always an rvalue reference. If T
is of type X&
or X const&
, then reference collapsing turns T&&
into X&
or X const&
.
最后,在类型推导上下文中, T&
会得出 T
为 X
, X&
, X const&
或 X const&
,具体取决于参数的类型,因此可以用作转发引用。
Finally, T&&
in a type deduction context will deduce T
as X
, X&
, X const&
or X const&&
depending on the type of the argument, and hence can act as a "forwarding reference".
这篇关于为什么右值引用变量不是右值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!