通过参考文献的参考直观地理解函数
可能的重复:
T&&是什么?在 C++11 中意味着什么?
由于某种原因,这超出了我的直觉,我在互联网上找不到任何解释。 C++ 函数获取引用的引用意味着什么?例如:
void myFunction(int&& val); //what does this mean?!
我理解按引用传递的想法,因此
void addTwo(int& a)
{
a += 2;
}
int main()
{
int x = 5;
addTwo(x);
return 0;
}
对我来说很有效并且很直观。
Possible Duplicate:
What does T&& mean in C++11?
For some reason, this is eluding my intuition, and I cannot find any explanation on the internet. What does it mean for a C++ function to take a reference of a reference? For example:
void myFunction(int&& val); //what does this mean?!
I understand the idea of passing-by-reference, so
void addTwo(int& a)
{
a += 2;
}
int main()
{
int x = 5;
addTwo(x);
return 0;
}
works and is intuitive to me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是引用的引用,而是一种名为 右值引用 的新语言功能,表示(非正式地)对内存中对象的引用,该对象未在程序中的其他地方引用,并且可以被破坏性修改。例如,函数的返回值可以通过右值引用捕获,就像引入到表达式中的临时值一样。
右值引用可用于多种目的。从大多数C++程序员的角度来看,它们可以用来实现移动语义,由此,可以通过将旧对象的内容从旧对象“移动”到新对象中来初始化新对象。您可以使用它从 C++11 中的函数返回巨大的对象,而无需花费巨大的成本来复制该对象,因为用于捕获返回值的对象可以使用移动构造函数进行初始化,只需从临时对象中窃取内部结构即可由 return 语句创建。
移动语义与复制语义正交,因此对象可以移动但不可复制。例如,std::ofstream 不可复制,但它们是可移动的,因此您可以使用移动行为从函数返回 std::ofstream。目前在 C++03 中无法完成此操作。例如,这段代码在 C++03 中是非法的,但在 C++11 中完全没问题(并且受到鼓励!):
直观上,采用右值引用的函数是一个(可能)试图通过以下方式避免昂贵的副本的函数:将旧对象的内容移动到新对象中。例如,您可以通过让构造函数接受右值引用来为类向量对象定义一个移动构造函数。如果我们将向量表示为数组指针、数组容量和已使用空间的三元组,我们可以按如下方式实现其移动构造函数:
值得注意的是,当我们清除
rhs 在构造函数的末尾,我们最终将
rhs
置于这样一种状态,即nullptr
代码>,自释放以来nullptr
是安全的),并且为了阐明 (2),右值引用的一个有趣用例是能够在对象之间显式移动值。例如,考虑一下
swap
的惯用实现:此代码是合法的,但有点不寻常。特别是,它最终会制作三个副本 - 首先将
temp
设置为lhs
的副本,一旦将lhs
设置为lhs
的副本rhs
,并一度将rhs
设置为temp
的副本。但我们真的不想在这里制作任何副本;相反,我们只想打乱这些值。因此,在 C++11 中,您将能够使用std::move
函数显式获取对象的右值引用:现在,根本不进行任何复制。我们将
lhs
的内容移动到temp
中,然后将rhs
的内容移动到lhs
中,然后移动内容temp
到rhs
中。在此过程中,我们将lhs
和rhs
暂时置于“清空”状态,然后再将新值放入其中。重要的是,在编写将内容移出对象的代码时,我们要使对象处于某种格式良好的状态,以便该代码正常工作。This is not a reference of a reference, but rather a new language feature called an rvalue reference that represents (informally) a reference to an object in memory that isn't referenced elsewhere in the program and can be destructively modified. For example, the return value of a function can be captured by an rvalue reference, as can temporary values introduced into expressions.
Rvalue references can be used for a variety of purposes. From the perspective of most C++ programmers, they can be used to implement move semantics, whereby a new object can be initialized by "moving" the contents of an old object out of the old object and into a new object. You can use this to return huge objects from functions in C++11 without paying a huge cost to copy the object, since the object used to capture the return value can be initialized using the move constructor by just stealing the internals from the temporary object created by the return statement.
Move semantics are orthogonal to copy semantics, so objects can be movable without being copyable. For example,
std::ofstream
s are not copyable, but they will be movable, so you could returnstd::ofstream
s from functions using the move behavior. This currently cannot be done in C++03. For example, this code is illegal in C++03 but perfectly fine (and encouraged!) in C++11:Intuitively, a function that takes an rvalue reference is a function that (probably) is trying to avoid an expensive copy by moving the contents of an old object into a new object. For example, you could define a move constructor for a vector-like object by having that constructor take in an rvalue reference. If we represent the vector as a triple of a pointer to an array, the capacity of the array, and the used space, we might implement its move constructor as follows:
It's important to notice that when we clear out
rhs
at the end of the constructor that we end up puttingrhs
into such a state thatnullptr
, since freeingnullptr
is safe), andTo shed some light on (2), one interesting use case for rvalue references is the ability to explicitly move values around between objects. For example, consider this idiomatic implementation of
swap
:This code is legal, but it's a bit unusual. In particular, it ends up making three copies - first when setting
temp
equal to a copy oflhs
, once settinglhs
to be a copy ofrhs
, and once settingrhs
to be a copy oftemp
. But we don't really want to be making any copies at all here; instead, we just want to shuffle the values around. Consequently, in C++11, you'll be able to explicitly get rvalue references to objects by using thestd::move
function:Now, no copies are made at all. We move the contents of
lhs
intotemp
, then move the contents ofrhs
intolhs
, then moves the contents oftemp
intorhs
. In doing so, we left bothlhs
andrhs
in an "emptied" state temporarily before putting new values into them. It's important that when writing the code to move the contents out of an object that we leave the object in a somewhat well-formed state so that this code works correctly.这不是对参考的参考。这是 C++0x 中为所谓的 右值引用引入的新语法。
It's not a reference to a reference. It's a new syntax introduced in C++0x for so-called Rvalue references.