为什么 C++0x 右值引用不是默认值?
即将推出的 C++ 标准 C++0x 的一项很酷的新功能是“右值引用”。 右值引用类似于左值(普通)引用,不同之处在于它可以绑定到临时值(通常,临时值只能绑定到 const
引用):
void FunctionWithLValueRef(int& a) {…}
void FunctionWithRValueRef(int&& a) {…}
int main() {
FunctionWithLValueRef(5); // error, 5 is a temporary
FunctionWithRValueRef(5); // okay
}
那么,为什么它们发明一种全新的类型,而不是仅仅删除对普通引用的限制以允许它们绑定到临时引用?
One of the cool new features of the upcoming C++ standard, C++0x, are "rvalue references." An rvalue reference is similar to an lvalue (normal) reference, except that it can be bound to a temporary value (normally, a temporary can only be bound to a const
reference):
void FunctionWithLValueRef(int& a) {…}
void FunctionWithRValueRef(int&& a) {…}
int main() {
FunctionWithLValueRef(5); // error, 5 is a temporary
FunctionWithRValueRef(5); // okay
}
So, why did they invent a whole new type, instead of just removing the restrictions on normal references to allow them to be bound to temporaries?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是毫无意义的。 您将更改函数中的事物,并且更改将立即丢失,因为该事物实际上是临时的。
之所以使用新类型,是因为需要能够确定什么实际上是右值,什么不是。 只有这样你才能真正将它们用于它们所使用的很酷的东西。
现在,如果你有一些右值并将其传递给 toupper,则可以直接修改右值,因为我们知道临时值无论如何都是一次性的东西,所以我们也可以只更改它而无需复制它。 此外,同样的观察也适用于称为移动构造函数和移动赋值的东西。 右手边没有被复制,但它的东西只是被偷走了并移动到
*this
。如果您说右值可以绑定到非常量左值引用,那么您将无法确定它最终是引用左值(命名对象)还是右值(临时)。
它可能鲜为人知,但无论如何很有用,您可以将左值或右值引用限定符放在成员函数上。 下面是一个示例,它自然地将右值引用的现有语义扩展到隐式对象参数:
现在,您不能再说
“这是令人困惑的,并且在大多数情况下没有真正意义”。 上面的
&
的作用是说赋值运算符只能在左值上调用。 通过放置&&
,可以对右值执行相同的操作。It would be pointless. You would change the thing in the function, and the change would be lost immediately because the thing was actually a temporary.
The reason for the new type stems from the need to be able to decide what actually is an rvalue and what not. Only then you can actually use them for the cool things they are used.
Now, if you have some rvalue and pass it to toupper, the rvalue can directly be modified, because we know the temporary is a throw-away thing anyway, so we can aswell just change it and don't need to copy it. Also, the same observation is used for the thing called move-constructors and move-assignment. The right hand side is not copied, but its things are just stolen away and moved to
*this
.If you were to say that rvalues can bind to non-const lvalue references, then you would have no way to figure out whether that references an lvalue (named object) or an rvalue (temporary) in the end.
It's probably more little know, but useful anyway, you can put lvalue or rvalue ref-qualifiers on a member function. Here is an example, which naturally extends the existing semantics of rvalue references to the implicit object parameter:
Now, you can't anymore say
Which is confusing and is not really making sense most of the time. What the
&
above does is saying that the assignment operator can only be invoked on lvalues. The same can be done for rvalues, by putting&&
.因为添加新类型的引用允许您编写方法的两个重载:
接受新类型引用的版本允许修改它接收的变量,因为该变量不会在其他任何地方使用。 所以它可以“窃取”其中的内容。
这就是添加此功能的全部原因; 保留一种类型的参考不会达到预期的目标。
Because adding a new kind of reference allows you to write two overloads of a method:
The version that accepts the new kind of reference is allowed to modify the variable it receives, because that variable isn't going to be used anywhere else. So it can "steal" the contents of it.
This is the whole reason this feature was added; retaining one type of reference wouldn't achieve the desired goal.