4

所以我真的很惊讶地发现在这段代码中:

void AddLayer( shared_Layer_ptr && pNewLayer_p ){

        m_layers.push_back( pNewLayer_p ); // *
    }

被调用的 push_back 是“& param”,而不是“&& param”版本。m_layers 是一个 std::vector。由于 pNewLayer_p 是一个“&&”,我虽然它是一个该死的右值。我设法调用 push_back("&& param") 的唯一方法是使用 std::move:

m_layers.push_back( std::move(pNewLayer_p) );

对我来说似乎是多余的,因为 pNewLayer_p 已经是一个“&&”。我肯定错过了一些东西,它是什么?

4

2 回答 2

2

想想如果它移动会发生什么pNewLayer

void AddLayer( shared_Layer_ptr && pNewLayer_p ){
    m_layers.push_back( pNewLayer_p );
    // what if pNewLayer_p is already moved
    another_m_layers.push_back( pNewLayer_p );
}

因此,您必须std::move明确使用:

void AddLayer( shared_Layer_ptr && pNewLayer_p ){
    m_layers.push_back( pNewLayer_p );
    another_m_layers.push_back( std::move(pNewLayer_p) );
}

如果右值引用只能在函数中出现一次,那肯定会削弱 C++ 的一些功能。

于 2013-05-29T01:14:52.647 回答
2

pNewLayer_p是一个右值引用,但它本身不是一个右值——主要是因为它有一个名字。Rvalues 在标准中定义如下:

(3.10/1) 右值(历史上称为右值,因为右值可能出现在赋值表达式的右侧)是一个 xvalue、一个临时对象 (12.2) 或其子对象,或者一个与一个东西。

换句话说,右值是字面量、临时值和其他未命名的对象(例如 xvalues,即刚刚由函数返回但尚未分配给任何东西的值)。

代码中的右值引用pNewLayer_p是一个命名对象,因此它本身就是一个左值。应用std::move到它,形式上是一个函数,将它(形式上)变成从函数返回的东西,即一个 xvalue,它是一个右值,您可以将其传递给push_back. 这就是std::move存在的意义。

(注意:以上假设shared_Layer_ptr是一个类型,而不是模板参数。如果是模板参数,shared_Layer_ptr &&则将是所谓的通用引用,即它可能是左值引用或右值引用,具体取决于模板的实例化方式. 在这种情况下,std::forward将是适当的函数来代替std::move.)

于 2013-05-29T01:05:04.813 回答