К примеру имеется следующий код:
// 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, и используется вторая версия, которая может принять просто ссылку на строку, не константную, как более точное, не пребующее приведения типа сответствие.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости