#новичкам
Пользователи 98-го стандарта недоумевали, почему они обязаны при наличии инициализатора указывать полный тип переменной при ее определении. "Если я еще раз напишу полный тип итератора, то я устрою Роскомнадзор", "Вы что, хотите, чтобы я пальцы стёр?!" и тд. У многих были такие мысли. И это, вообще говоря, было очень странно, потому что компилятор уже на тот момент мог сам выводить тип на основе типа другого выражения!
В шаблонах.
Вам же не обязательно писать в шаблонных функциях тип шаблонного аргумента. В некоторых случаях компилятор за вас это может сделать.
template <class Container>
size_t my_size(const Container& container)
{
return container.size();
}
std::cout << my_size(std::vector<int>(10, 0)) << std::endl;
Здесь выведется 10 и, как вы видите, для функции my_size мы не указывали явным образом шаблонный тип.
Ну и раз уже есть наработанная схема, к которой разработчики уже привыкли, то почему бы именно ее не использовать в качестве основы вывода типов для auto? Этим риторическим вопросом задались контрибьютеры в 11-й стандарт и теперь у нас действительно есть ключевое слово auto, для которого вывод типов практически ничем не отличается от вывода типов для шаблонных функций!
Поэтому надо понимать, что это за зверь такой, чтобы осознанно использовать auto.
Чтобы мы все понимали, о чем конкретно будем говорить, посмотрим на следующий псевдокод:
template <class T>
void func(ParamType param) {...}
func(expression);
Все будем разбирать на примере подобной шаблонной функции. Так вот процесс вывода типов ParamType и Т на основании типа выражения expression - это и есть вывод шаблонных типов.
Небольшой пример:
template <class T>
size_t my_size(const std::vector<T>& vec) {...}
template <class T>
void fun(const T& param) {...}
my_size(std::vector<int>(10, 0));
int i = 42;
fun(i)
В случае c my_size ParamType - const std::vector<T>&, а тип T - int. В случае с fun ParamType принимает вид типа Т, обвешанного побрякушками, типа const- и ссылочного квалификаторов. Здесь ParamType = const T&, а Т = int.
То есть ParamType - все то, что стоит слева от имени шаблонного параметра, и на основе выведенного ParamType уже принимается решение о типе Т. Поэтому очень важно понимать не только, какой тип имеет expression, но и какой вид принимает ParamType. Есть всего 3 мажорных варианта:
1) ParamType - указатель или ссылка, но не универсальная ссылка.
2) ParamType - универсальная ссылка.
3) ParamType - ни указатель, ни ссылка.
Все это в следующих постах будем раскрывать подробнее.
Use deduction. Stay cool.
#cppcore #template