Существует простой способ выяснить, когда использовать std::forward
.
Представьте, что ваш входящий аргумент был вместо T&& t
только T t
- параметр значения вместо ссылки пересылки. Если вы вызовете std::move(t)
во втором случае, вызов std::forward<T>(t)
в первом случае - хорошая идея.
std::forward
- условный ход. Он будет вызывать move
, если ссылка была переданной rvalue и будет делать в основном ничего, если это не значение rvalue.
Следующий вопрос: когда вы должны указать move
значение параметра?
Ну, первое общее правило: вы должны переместить параметр значения в последний раз, когда вы когда-либо ссылаетесь на него в своей области. Вы отмечаете свое состояние как «царапины» и что оно должно быть переработано в этой последней операции.
Есть еще несколько мест для использования move
.
Если вы разбить его на отдельные компоненты (например, в части кортежа), и вы знаете, что доступ будет изолировано в части (std::get<N>
или .member
), и нет инварианты, которые будут нарушены, то move
скажет код, что компонент может быть вырван из объекта. Вы можете в конечном итоге вызвать move
по одной и той же переменной, но каждый раз, когда вы концептуально перемещаете только одну часть.
Это иногда отличается от вызова move
на самом компоненте, так как std::get<i>(std::move(foo))
будет вести себя иначе, чем std::move(std::get<i>(foo))
когда foo
содержит эталонные параметры.
И использование 'std :: forward' более одного раза по одному и тому же параметру, скорее всего, является ошибкой, так как rvalues, вероятно, будут удалены при первом вводе' std :: forward'. – JohnB