К примеру имеется следующий код:
// main.cpp
#include <cstdlib>
#include <iostream>
#include <string>
void foo(const std::string &t) {
std::cout << "lvalue" << std::endl;
std::cout << t << std::endl;
}
void foo(std::string &&t) {
std::cout << "rvalue" << std::endl;
std::cout << t << std::endl;
}
int main() {
std::string alpha = "tmp";
foo(alpha);
return EXIT_SUCCESS;
}
При выполнении которого мы ожидаемо увидим, что был использован первый вариант функции с константной ссылкой lvalue. Однако если функции заменить шаблонами:
// main.cpp
#include <cstdlib>
#include <iostream>
#include <string>
template <typename T>
void foo(const T &t) {
std::cout << "lvalue" << std::endl;
std::cout << t << std::endl;
}
template <typename T>
void foo(T &&t) {
std::cout << "rvalue" << std::endl;
std::cout << t << std::endl;
}
int main() {
std::string alpha = "tmp";
foo(alpha);
return EXIT_SUCCESS;
}
То можно увидеть, что вызывается второй вариант функции с rvalue ссылкой. Почему? Как инстанцируются эти шаблоны?
PS конечно, можно добавить std::enable_if<std::is_rvalue_reference<T&&>::value>::type, но меня интересует почему так происходит.
В шаблонах && - это просто универсальная ссылка, которая может быть lvalue, может rvalue.
В первом случае без шаблонов нет rvalue переменной, только lvalue, потому и используется const-версия, принимающая lvalue.
Во втором - у нас переменная не является const, и используется вторая версия, которая может принять просто ссылку на строку, не константную, как более точное, не пребующее приведения типа сответствие.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости