首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rvalue引用:为什么不隐式移动Rvalue?

Rvalue引用:为什么不隐式移动Rvalue?
EN

Stack Overflow用户
提问于 2013-01-16 05:00:37
回答 2查看 403关注 0票数 10

在关于C++ rvalue引用(http://www.artima.com/cppsource/rvalue.html)的Artima文章中,有几个词是:这就是为什么在传递给基类时必须使用move(x)而不是x。这是移动语义的一个关键安全特性,旨在防止意外地从某个命名变量中移动两次。

我想不出这种双重动作能起什么作用。你能举个例子吗?换句话说,如果T&&的所有成员都是rvalue引用而不仅仅是引用,那么会有什么问题呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-16 05:15:08

考虑一下这种情况:

代码语言:javascript
复制
void foo(std::string x) {}
void bar(std::string y) {}

void test(std::string&& str)
{
    // to be determined
}

我们想用str调用foo,然后用str调用bar,两者都具有相同的值。最好的方法是:

代码语言:javascript
复制
foo(str); // copy str to x
bar(std::move(str)); // move str to y; we move it because we're done with it

这样做是错误的:

代码语言:javascript
复制
foo(std::move(str)); // move str to x
bar(std::move(str)); // move str to y...er, except now it's empty

因为在第一次移动之后,str的值是未指定的。

因此,在rvalue引用的设计中,这种隐式移动并不存在。如果是的话,我们上面最好的方法就行不通了,因为第一次提到str将是std::move(str)

票数 18
EN

Stack Overflow用户

发布于 2013-01-16 08:24:00

在我看来,如果我们有一些rvalue引用x:

代码语言:javascript
复制
T&& x = ...;

我们用x作为参数调用了一些函数:

代码语言:javascript
复制
f(x)

我们需要某种方法来告诉f它是否会损坏x(或者“取得x的所有权”,或者“是最后一个使用x的客户机”)。

设计此功能的一种方法是对每个呼叫进行限定:

代码语言:javascript
复制
f(yours_now(x)) // ok to damage
f(still_mine(x)) // dont damage

不合格的电话是非法的。

另一种方法是将一种方式设置为默认:

以下任一项:

代码语言:javascript
复制
f(yours_now(x)) // ok to damage
f(x) // dont damage

代码语言:javascript
复制
f(x) // ok to damage
f(still_mine(x)) // dont damage

因此,如果我们一致认为每一次使用都过于庞大,我们应该默认一种方式,哪一种是最好的呢?那么,让我们看看在这两种情况下不小心选择缺省值的代价:

在第一种情况下,损坏是可以的,但我们不小心说它不是。在这种情况下,我们失去了性能,因为一个不必要的复制,但除此之外,没有什么大不了的。

在第二种情况下,损坏物体是不可能的,但我们意外地说是这样的。这可能会导致很难检测程序中的逻辑错误,因为当f返回时,x现在处于损坏状态,但作者预期情况并非如此。

所以第一个例子是选择什么,因为它“更安全”。

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

https://stackoverflow.com/questions/14351669

复制
相关文章

相似问题

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