C++ 将局部变量命名为右值ref有什么意义吗?
假设代码已编译,则以下各项之间是否存在差异:C++ 将局部变量命名为右值ref有什么意义吗?,c++,c++11,rvalue-reference,C++,C++11,Rvalue Reference,假设代码已编译,则以下各项之间是否存在差异: A && a = ..... const A && a = ..... 及 ?a是函数或方法中的局部变量,而不是参数 通过给右值引用一个名称(a),它实际上是作用域其余部分的左值?i、 e.即使使用前一种形式,在将a传递到另一个函数时,您也必须使用move(a)来启用偷窃 我理解第二个表单可能存在其他问题,这会妨碍编译,例如,您不能对临时表单进行(非常量)引用。所以,是的,我很想知道所有的差异,但首先我想确认我的直
A && a = .....
const A && a = .....
及
?a
是函数或方法中的局部变量,而不是参数
通过给右值引用一个名称(a
),它实际上是作用域其余部分的左值?i、 e.即使使用前一种形式,在将a
传递到另一个函数时,您也必须使用move(a)
来启用偷窃
我理解第二个表单可能存在其他问题,这会妨碍编译,例如,您不能对临时表单进行(非常量)引用。所以,是的,我很想知道所有的差异,但首先我想确认我的直觉,它们对于范围的其余部分是完全等效的
更新:作为@KerrekSB重申的“临时”问题的一个例子,有时您必须简单地引用const
。在这种情况下,我的问题是:
A && a = .....
const A && a = .....
及
这项工作:
int foo();
int && a = foo();
这并不是:
int & b = foo(); // error, cannot bind rvalue to non-const ref
A&&A=…
和A&A=…
之间的区别在于前者可以绑定到临时文件,而后者则不能。C++标准现在指定引用必须是非易失性const或rValst引用绑定到临时(参见85.3引用[dCL init .REF]),它可以延长临时的生存期(参见12.2 [类。临时])。
<>编辑:如果你考虑R值引用允许你做什么,他们必须能够绑定到暂时的,否则,你将不能在C++中表达移动语义。
可能有不同之处:(您需要检查等级库,并修改/修复等级库的该部分)
这两种情况的不同之处在于decltype(a)
。(回答我自己的问题只是为了总结我所学到的东西。)
总之,A&A=…
和A&&A=…
之间以及const A&A=…
和const A&&A=…
之间有什么区别?如果它们是函数参数的名称,那么它显然会影响函数查找,但我只是在谈论局部变量。区别是:
A&A=foo();
无法绑定到临时变量(这里没有新内容),但其他三种形式可以并且将延长局部变量的生存期decltype(a)
将不同运算符&
或运算符&
转换可供选择A &&a =...;
foo(a);
将调用foo(A&&)
,但需要调用foo(move(A))
C++03程序员可以相当安全地使用A&&A=
来延长临时程序的生命周期,而不必担心其他意外的差异
(感谢大家)我对所有这些C++11混乱的东西都是陌生的;
foo
的返回值在哪里?他说他在他的帖子中知道这一点:D@Seth:指的是C++11,但它所在的位置肯定不是。我在我的问题中已经提到:-)“例如,你不能(非常量)引用临时”我认为这是早期版本的g++给出的错误消息。我将适当地编辑我的问题。@SethCarnegie,暂时忽略&&
<代码>常量int&a=foo()代码>保留在堆栈上,但不会被破坏。调用任何函数时,调用方(据我所知)在堆栈上留出空间来存储返回值。我认为这个const&
符号会导致在返回后,将该空间神奇地重新解释为一个新的局部变量。@SethCarnegie,检查以澄清我们正在讨论的C++11之前的问题。有人(引用标准?)说“临时变量在语句末尾死亡,除非它们绑定到常量引用,在这种情况下,当引用超出范围时它们就会死亡”不,如果这是你唯一的问题,那么常量和常量A=…
和常量A=…
之间没有区别。@ildjarn,这是我的主要问题。以及非常量版本(假设代码已编译)。a
的生存期或其他任何可能导致程序行为稍有不同的方面没有区别?如果你是说,a const&a=…
和a&&a=…
之间有什么区别,那么唯一的区别就是允许您修改非常量数据成员并调用后者的非常量成员函数,而不是前者——两者都是相同的,它们只是在延长临时数据的生存期。@ildjarn,完美。在互联网上关于&&
的所有讨论中,我没有看到任何人明确指出它可以作为延长临时用户生命的一种方式。这种行为似乎是一种意想不到的好处。(或者有些人会对此表示不满!“临时工应该是临时的,达尔尼特!”@Aaron这是一处精心设计的房产。Foreach循环将for循环中给定的容器存储为auto&&c=container
。如果容器是临时的,那么延长生存期是很重要的。我最初喜欢这个答案,因为它增加了我对是否以及何时可以初始化这样的变量的了解。我知道A&
不会绑定临时变量,但我不知道A&&
会绑定临时变量。(事实上,一开始我认为std::move是一种核心语言魔法。)但我很好奇它们在使用之后是否有什么不同