Так что я просто удивился, обнаружив, что в этом коде:
void AddLayer( shared_Layer_ptr && pNewLayer_p ){
m_layers.push_back( pNewLayer_p ); // *
}
Вызываемый push_back является «& парам «а не то»&& param «версия. m_layers является std :: vector.
Поскольку pNewLayer_p является «&&»Я думал, что это чертово значение … Единственный способ, которым мне удается получить push_back («&& Вызывается param «) с помощью std :: move:
m_layers.push_back( std::move(pNewLayer_p) );
Мне кажется излишним, так как pNewLayer_p уже «&&».. Я уверен, что что-то упустил, что это?
pNewLayer_p
является ссылкой на rvalue, но сама по себе не является rvalue — в основном потому, что у нее есть имя. Значения определяются в Стандарте следующим образом:
(3.10 / 1) rvalue (так называемый, исторически, потому что rvalue мог появиться в правой части выражения присваивания) является xvalue, временным объектом (12.2) или его подобъектом, или значением, которое не связано с объект.
Другими словами, rvalues - это литералы, временные и другие неназванные объекты (такие как xvalues, то есть значения, которые только что были возвращены функцией, но еще никому не были назначены).
Rvalue ссылка pNewLayer_p
в вашем коде есть именованный объект, поэтому он сам является lvalue. применение std::move
для него, который формально является функцией, превращает его (формально) во что-то, возвращаемое из функции, то есть в xvalue, которое является значением, которое вы можете передать в версию перемещения push_back
, Это то, что std::move
существует для.
(Примечание: вышеизложенное предполагает, что shared_Layer_ptr
это тип, а не параметр шаблона. Если это параметр шаблона, shared_Layer_ptr &&
будет так называемой универсальной ссылкой, то есть это может быть ссылка lvalue или ссылка rvalue в зависимости от того, как создается экземпляр шаблона. В этом случае, std::forward
будет подходящей функцией для использования вместо std::move
.)
Подумай, что случится, если он начнет двигаться 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) );
}
Если ссылка на rvalue может появляться в функции только один раз, это определенно удалит некоторую мощность из C ++.