3

只是为了确保很好地理解引擎盖下的内容......问题在代码中作为注释

   void test(int && val)
    {
        val=4;
    }//val is  destroyed here ?

int main()
{  
    int nb;
    test(std::move(nb));
    //undefined behavior if I reference here nb ?
    std::cout << nb;
    nb=5;
    std::cin.ignore();    
}
4

6 回答 6

3

您必须了解,对某物的右值引用不会神奇地移动该值。它所做的只是使对临时对象的非 const 引用成为可能。

在您的示例中,此参考与普通参考没有什么不同,因为您在这里没有任何临时对象。你是必须让“行动”发生的人。

例如,如果您定义 int 的值为 时为空0,并且您编写了一个接受右值引用的函数,使用它并将传递的值设置为0,那么您将前一个值从 int 中“移出”。调用此函数后,它将包含0. 但那是因为是这样定义的。

现在,对于整数来说,这没有多大意义,但想象一下你正在处理一个指向一大块内存的指针。

于 2011-07-28T20:40:58.247 回答
3

移出的值处于有效但未指定的状态。据我所知,这基本上意味着它可能包含任何值,但它必须包含一些值,并且访问它是合法且已定义的行为。

于 2011-07-28T21:39:17.393 回答
1

这不是未定义的行为,因为您实际上从未从val函数内部移动。std::move只是变成nb一个右值。这实际上只有在你有其他模棱两可的重载时才有意义test

于 2011-07-28T20:14:01.947 回答
0
//val is  destroy here ?

与参数类型相同的答案是const int& val

//undefined behavior if I reference here nb ?

没有。但是没有指定打印出来的值。这与“未定义的行为”不同,这意味着任何事情都可能发生。如果它是未定义的行为,则意味着您的磁盘可能会被重新格式化。

于 2011-07-28T20:14:29.303 回答
0

大多数情况下,右值引用对您很有用,当您编写一个新类时,您关心复制它的成本,并且您想编写一个移动构造函数。

使用别人的移动构造函数(只要它设计良好)对你来说几乎是不可见的。

例如,何时添加移动构造函数和移动赋值运算符才真正开始有所作为?

因此,如果您想探索移动语义,我建议您使用移动构造函数构建一些示例代码。

于 2011-07-28T20:26:14.533 回答
0

有关 std::move 的详细说明,请参见此处。除非您不开始使用移动构造函数,否则您将无法有效地使用此新功能。另外,我认为对于复制没有开销的原始类型没有任何意义。

于 2011-07-28T21:32:26.993 回答