绑定可修改的右值引用到可修改的左值

时间:2011-08-26 22:07:08

标签: c++ reference move-semantics forward rvalue

我有3个问题:

  1. 我可以将左值直接绑定到右值参考吗?

  2. std::move()

  3. 对象会发生什么变化
  4. std :: move和std::forward之间有什么区别?

  5. struct myStr{
        int m_i;
    };
    
    void foo(myStr&& rs) { }
    
    myStr rValueGene()
    {
        return myStr();
    }
    
    int main() 
    {
        myStr mS= {1};
        foo(rValueGene()); //ok passing in modifiable rvalue to rvalue reference
    
        // To Question 1:
        //below initilize rvalue reference with modifiable lvalue, should be ok
        //but VS2010 gives a compile error: error C2440: 'initializing' : cannot convert from    'myStr' to 'myStr &&' 
        //Is this correct ?
        myStr&& rvalueRef = mS;
    
        //by using std::move it seems ok, is this the standard way of doing this 
        //to pass a lvalue to rvalue reference
        //myStr&& rvalueRef = std::move(mS);
    
        // To Question 2:    
        //also what happens to mS object after std::move ?
        //destroyed , undefined ?
    }
    

2 个答案:

答案 0 :(得分:3)

  

1>我可以将左值直接绑定到右值参考吗?

不是没有明确的演员(即:std::move)。

  

2> std :: move()的对象会发生什么?

在实际移动之前没有任何东西。所有std::move都返回一个r值参考,你给它。实际移动发生在相关类型的移动构造函数/赋值中。

  

3> std :: move和std :: forward之间的区别是什么?

std::move用于移动; std::forward用于转发。这听起来很滑稽,但这就是主意。如果您打算移动对象,则使用std::move。如果您打算转发对象,请使用std::forward

转发使用允许在引用类型之间进行转换的专用语义,以便在调用之间保留引用性质。所有这些的具体细节都非常......技术性。

std::move 始终返回&&。如果给它一个l值引用,它将返回一个r值引用。如果为其指定值类型,则返回对该值的r值引用。等等。

std::forward 总是返回&amp;&amp;。从语法上讲,std::forward只是在做static_cast<T&&>。但是,由于专门的语法围绕着铸造到&amp;&amp;类型,这个演员并不总是返回&amp;&amp;。是的,这很奇怪,但它解决了转发问题,所以没人关心。这就是为什么它包含在std::forward中,而不是必须自己明确地执行static_cast

答案 1 :(得分:1)

问题1.是的,编译器是正确的。

问题2.什么都没发生。 std::move只是向rvalues投射东西。

但是,如果您使用std::movemS(或myStr)传递给foo,那么该函数可能会认为它可以“窃取”该对象因此,mS可能在函数调用后最终处于未指定的状态。