为什么C ++ 0x右值引用不是默认值? [英] Why are C++0x rvalue reference not the default?

查看:241
本文介绍了为什么C ++ 0x右值引用不是默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即将到来的C ++标准C ++ 0x的一个很酷的新功能是右值引用。右值引用类似于一个左值(正常)引用,除了它可以绑定到一个临时值(通常,临时只能绑定到 const 引用) :

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?

推荐答案

你将改变函数中的东西,并且改变将立即丢失,因为事实上是一个临时的。

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.

string toupper(string && s) { // for nonconst rvalues
    for(char &c : s) make_uppercase(c);
    return move(s); // move s into a returned string object
}

string toupper(string const& s) { // for the rest
    // calls the rvalue reference version, by passing 
    // an rvalue copy.
    return toupper(string(s));
}

现在,如果你有一些右值并传递给toupper,直接修改,因为我们知道临时是一个抛弃的东西,所以我们可以改变它,而不需要复制它。此外,相同的观察用于称为移动构造函数和移动赋值的事情。右侧不复制,但它的东西只是被偷走了,并移动到 * this

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.


这可能是更多的知道,但有用无论如何,你可以把左值或右值成员函数上的ref-qualifiers。下面是一个例子,它自然地将右值引用的现有语义扩展到隐式对象参数:

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:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

现在,您不能再说

string() = "hello";

这是令人困惑的,大多数时候并不真正有意义。上面的& 是说赋值运算符只能在左值上调用。对于右值也可以这样做:&&&

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 &&.

这篇关于为什么C ++ 0x右值引用不是默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆