Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C++;0x rvalue引用不是默认值吗? 即将到来的C++标准CC++ +0x的一个新特性是“R值引用”。RValk引用类似于LValk(正常)引用,除了它可以绑定到临时值(通常,临时只能绑定到 const 参考):_C++_C++11_Lvalue_Rvalue - Fatal编程技术网

为什么C++;0x rvalue引用不是默认值吗? 即将到来的C++标准CC++ +0x的一个新特性是“R值引用”。RValk引用类似于LValk(正常)引用,除了它可以绑定到临时值(通常,临时只能绑定到 const 参考):

为什么C++;0x rvalue引用不是默认值吗? 即将到来的C++标准CC++ +0x的一个新特性是“R值引用”。RValk引用类似于LValk(正常)引用,除了它可以绑定到临时值(通常,临时只能绑定到 const 参考):,c++,c++11,lvalue,rvalue,C++,C++11,Lvalue,Rvalue,那么,他们为什么要发明一种全新的类型,而不是仅仅取消对普通引用的限制,让它们绑定到临时引用?这将是毫无意义的。您将更改函数中的内容,而更改将立即丢失,因为该内容实际上是临时的 新类型的原因在于需要能够确定什么实际上是右值,什么不是右值。只有这样,你才能真正地用它们来做那些很酷的事情 string toupper(string && s) { // for nonconst rvalues for(char &c : s) make_uppercase(c);

那么,他们为什么要发明一种全新的类型,而不是仅仅取消对普通引用的限制,让它们绑定到临时引用?

这将是毫无意义的。您将更改函数中的内容,而更改将立即丢失,因为该内容实际上是临时的

新类型的原因在于需要能够确定什么实际上是右值,什么不是右值。只有这样,你才能真正地用它们来做那些很酷的事情

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,右值可以直接修改,因为我们知道临时值是一次性的,所以我们也可以更改它,而不需要复制它。同样,对于称为移动构造函数和移动赋值的东西也使用了相同的观察结果。右手边没有被复制,但它的东西只是被偷走并移到了
*这个

如果您说右值可以绑定到非常量左值引用,那么您将无法确定它最终是引用左值(命名对象)还是右值(临时)


它可能不太为人所知,但无论如何都很有用,您可以在成员函数上放置左值或右值ref限定符。下面是一个示例,它自然地将右值引用的现有语义扩展到隐式对象参数:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};
现在,你不能再说了

string() = "hello";

这是令人困惑的,并且在大多数情况下没有真正意义。上面的
&
说明赋值运算符只能在左值上调用。通过放置
&&

也可以对右值执行同样的操作,因为添加一种新的引用允许您编写一个方法的两个重载:

void CopyFrom(MyClass &&c)
{
    dataMember.swap(c);
}

void CopyFrom(const MyClass &c)
{
    dataMember.copyTheHardWay(c);
}
允许接受新类型引用的版本修改它接收的变量,因为该变量不会在其他任何地方使用。所以它可以“窃取”它的内容


这就是添加此功能的全部原因;保留一种类型的引用不会达到预期的目标。

+1哇,感谢关于左值/仅右值成员调用的最后一部分!我读了很多关于C++0x的书,但没有看到任何关于这方面的内容(我想这是在最后一稿中,但我没有全部读过)。你能给我指一些关于这个功能的文档吗?这里有一个很好的概述:。在工作文件中,见8.3.5、9.3.1和13.3.1。感谢您的回答,这使其更加清晰。我只是不太理解右值引用。这比我想的更有意义。我想补充一句,这是一篇很棒的“傻瓜的右值参考”文章。rlbond,谢谢你的精彩文章。另一个伟大的例子是:我想知道为什么这张专辑获得了3张得票,但却得到了7张最受欢迎的票。我认为我从来没有在没有投票的情况下赞成过一个问题(除非我没有投票权或它被锁定)。我想知道为什么有人会以某种方式思考,然后他期望所有其他人都会像他那样做。我想知道为什么“友善并放弃投票”是一种不合理的期望。
void CopyFrom(MyClass &&c)
{
    dataMember.swap(c);
}

void CopyFrom(const MyClass &c)
{
    dataMember.copyTheHardWay(c);
}