【问题标题】:move semantics and Lifetime of variables when binding lvalue to rvalues reference将左值绑定到右值引用时移动变量的语义和生命周期
【发布时间】:2011-07-28 20:07:31
【问题描述】:

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

   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();    
}

【问题讨论】:

    标签: c++ c++11 move-semantics


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • “你必须明白,对某物的右值引用不会神奇地移动值”,是的
      • @Guillaume 如果我低估了您的专业知识,我深表歉意,但您的问题是“val 在这里被破坏了吗?”对我来说没有多大意义。 Val 是一个引用,所以是的,引用 val 在那一点被销毁,但是 val 引用的变量继续存在,直到它超出变量的范围,或者直到它为临时创建的表达式的 ; .
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:
        //val is  destroy here ?
        

        与参数类型为const int&amp; val 的答案相同。

        //undefined behavior if I reference here nb ?
        

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

        【讨论】:

        • 您能解释一下为什么在这种情况下未指定打印值吗?我原以为它会被很好地指定,因为函数内部没有执行实际的移动操作。
        • 我相信这种行为确实是明确规定的;它将nb 设置为四。不过,我可能对此有误,所以你能解释一下为什么它会有一个未指定的值吗?
        • 我显然对这个问题的解释不同。如果您不进行整个程序分析,那么要从中移动的对象的值是未指定的。在这种情况下,我在分析main时故意忽略了test()的定义。
        【解决方案5】:

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

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

        例如When will adding a move constructor and a move assignment operator really start make a difference?

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2015-10-02
            • 1970-01-01
            • 2017-12-06
            • 2015-11-18
            • 2014-10-31
            • 2017-04-13
            • 2014-01-02
            • 1970-01-01
            相关资源
            最近更新 更多