Я думаю, вы достаточно растеряны.Роль форварда только важна, когда в игру вступают универсальные ссылки, а универсальная ссылка - это что-то вроде T&& t
, но только , когда T является параметром шаблона.
Например, в void foo(X&& x);
x
это не ссылка на пересылку, это обычная ссылка на значение, и пересылка не имеет смысла.Скорее, вы используете std::move
, если хотите сохранить его rvaleness, в противном случае он становится l-значением:
void foo(X&& x) {
bar(x); // calls bar with an l-value x, x should be not moved from
baz(std::move(x)); // calls bar with an r-value x, x is likely moved from after this and probably unusable
}
Другими словами, вышеприведенная функция foo
была специально создана для получения ссылок на rvalue, так как онааргумент, и больше ничего не приму.Вы, как писатель функций, определили его контракт таким образом.
Напротив, в контексте, подобном template <class T> void foo(T&& t)
t
, это ссылка на пересылку.Из-за правила свертывания ссылок это может быть ссылка rvalue или lvalue, в зависимости от значения выражения, переданного функции foo на сайте вызова.В таком случае вы используете
template<class T>
void foo(T&& t) {
// bar is called with value matching the one at the call site
bar(std::forward<T>(t));
}