首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么C++0x rvalue reference不是默认的?

为什么C++0x rvalue reference不是默认的?
EN

Stack Overflow用户
提问于 2009-05-09 22:46:39
回答 2查看 3.9K关注 0票数 20

即将推出的C++标准C++0x的一个很酷的新特性是“右值引用”。右值引用类似于左值(正常)引用,不同之处在于它可以绑定到临时值(通常,临时值只能绑定到const引用):

代码语言:javascript
运行
复制
void FunctionWithLValueRef(int& a) {…}
void FunctionWithRValueRef(int&& a) {…}

int main() {
     FunctionWithLValueRef(5); // error, 5 is a temporary
     FunctionWithRValueRef(5); // okay
}

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-05-09 22:58:53

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

使用新类型的原因是需要能够确定什么是rvalue,什么不是。只有这样,你才能真正使用它们来做一些很酷的事情。

代码语言:javascript
运行
复制
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));
}

现在,如果您有一些rvalue并将其传递给toupper,则可以直接修改rvalue,因为我们知道临时值无论如何都是一个丢弃的东西,所以我们也可以直接更改它,而不需要复制它。同样,同样的观察也被用于移动构造函数和移动赋值函数。右侧没有被复制,但它的内容只是被偷走并移动到*this

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

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

代码语言:javascript
运行
复制
struct string {
    string& operator=(string const& other) & { /* ... */ }
};

现在,你不能再说

代码语言:javascript
运行
复制
string() = "hello";

这在大多数情况下是令人困惑的,也没有真正的意义。上面的&所做的是说明赋值运算符只能在左值上调用。对右值也可以这样做,只需放入&&

票数 44
EN

Stack Overflow用户

发布于 2009-05-09 22:59:13

因为添加新类型的引用允许您编写方法的两个重载:

代码语言:javascript
运行
复制
void CopyFrom(MyClass &&c)
{
    dataMember.swap(c);
}

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

接受新类型引用的版本可以修改它接收的变量,因为该变量不会在其他任何地方使用。所以它可以“窃取”其中的内容。

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

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/844241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档