Использование универсальных ссылок
Универсальные ссылки — это ссылки, которые могут быть либо lvalue, либо rvalue в зависимости от контекста. Они определяются с использованием шаблонов и синтаксиса
T&&
.
template <typename T>
void foo(T&& arg) {
// arg может быть как lvalue, так и rvalue
}
Ещё по теме: Универсальные ссылки.
Использование std::forward
Функция std::forward
используется для передачи параметров в их первоначальном виде (как lvalue или rvalue) при вызове других функций.
Пример без идеальной передачи
#include <iostream>
void process(int& x) {
std::cout << "Lvalue: " << x << std::endl;
}
void process(int&& x) {
std::cout << "Rvalue: " << x << std::endl;
}
template <typename T>
void foo(T&& arg) {
process(arg); // всегда вызывает process(int&)
}
int main() {
int a = 5;
foo(a); // вызывает process(int&)
foo(5); // вызывает process(int&)
return 0;
}
В этом примере аргумент всегда передается как lvalue, что не всегда желательно.
Пример с идеальной передачей
#include <iostream>
#include <utility> // для std::forward
void process(int& x) {
std::cout << "Lvalue: " << x << std::endl;
}
void process(int&& x) {
std::cout << "Rvalue: " << x << std::endl;
}
template <typename T>
void foo(T&& arg) {
process(std::forward<T>(arg)); // сохраняет тип и значение arg
}
int main() {
int a = 5;
foo(a); // вызывает process(int&)
foo(5); // вызывает process(int&&)
return 0;
}
std::forward
используется для сохранения типа и значения аргумента, что позволяет правильно вызвать перегруженные функции.