在关于C++ rvalue引用(http://www.artima.com/cppsource/rvalue.html)的Artima文章中,有几个词是:这就是为什么在传递给基类时必须使用move(x)而不是x。这是移动语义的一个关键安全特性,旨在防止意外地从某个命名变量中移动两次。
我想不出这种双重动作能起什么作用。你能举个例子吗?换句话说,如果T&&的所有成员都是rvalue引用而不仅仅是引用,那么会有什么问题呢?
发布于 2013-01-16 05:15:08
考虑一下这种情况:
void foo(std::string x) {}
void bar(std::string y) {}
void test(std::string&& str)
{
// to be determined
}我们想用str调用foo,然后用str调用bar,两者都具有相同的值。最好的方法是:
foo(str); // copy str to x
bar(std::move(str)); // move str to y; we move it because we're done with it这样做是错误的:
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)。
发布于 2013-01-16 08:24:00
在我看来,如果我们有一些rvalue引用x:
T&& x = ...;我们用x作为参数调用了一些函数:
f(x)我们需要某种方法来告诉f它是否会损坏x(或者“取得x的所有权”,或者“是最后一个使用x的客户机”)。
设计此功能的一种方法是对每个呼叫进行限定:
f(yours_now(x)) // ok to damage
f(still_mine(x)) // dont damage不合格的电话是非法的。
另一种方法是将一种方式设置为默认:
以下任一项:
f(yours_now(x)) // ok to damage
f(x) // dont damage或
f(x) // ok to damage
f(still_mine(x)) // dont damage因此,如果我们一致认为每一次使用都过于庞大,我们应该默认一种方式,哪一种是最好的呢?那么,让我们看看在这两种情况下不小心选择缺省值的代价:
在第一种情况下,损坏是可以的,但我们不小心说它不是。在这种情况下,我们失去了性能,因为一个不必要的复制,但除此之外,没有什么大不了的。
在第二种情况下,损坏物体是不可能的,但我们意外地说是这样的。这可能会导致很难检测程序中的逻辑错误,因为当f返回时,x现在处于损坏状态,但作者预期情况并非如此。
所以第一个例子是选择什么,因为它“更安全”。
https://stackoverflow.com/questions/14351669
复制相似问题