Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 | страница 20
Это редко приводит к каким-то отличиям на практике, но если вы знаете о преобразовании массивов в указатели, то разберетесь и в преобразовании функций в указатели.
Итак, у нас есть правила для вывода типов шаблонов, связанные с >auto
. В начале я заметил, что они достаточно просты, и по большей части так оно и есть. Немного усложняет жизнь отдельное рассмотрение согласованных lvalue при выводе типов для универсальных ссылок, да еще несколько “мутят воду” правила преобразования в указатели для массивов и функций. Иногда так и хочется, разозлившись, схватить компилятор и вытрясти из него — “А скажи-ка, любезный, какой же тип ты выводишь?” Когда это произойдет, обратитесь к разделу 1.4, поскольку он посвящен тому, как уговорить компилятор это сделать.
• В процессе вывода типа шаблона аргументы, являющиеся ссылками, рассматриваются как ссылками не являющиеся, т.е. их “ссылочность” игнорируется.
• При выводе типов для параметров, являющихся универсальными ссылками, lvalue-apгумeнты рассматриваются специальным образом.
• При выводе типов для параметров, передаваемых по значению, аргументы, объявленные как >const
и/или >volatile
, рассматриваются как не являющиеся ни >const
, ни >volatile
.
• В процессе вывода типа шаблона аргументы, являющиеся именами массивов или функций, преобразуются в указатели, если только они не использованы для инициализации ссылок.
1.2. Вывод типа >auto
Если вы прочли раздел 1.1 о выводе типов шаблонов, вы знаете почти все, что следует знать о выводе типа >auto
, поскольку за одним любопытным исключением вывод типа >auto
представляет собой вывод типа шаблона. Но как это может быть? Вывод типа шаблона работает с шаблонами, функциями и параметрами, а >auto
не имеет дела ни с одной из этих сущностей.
Да, это так, но это не имеет значения. Существует прямая взаимосвязь между выводом типа шаблона и выводом типа >auto
. Существует буквальное алгоритмическое преобразование одного в другой.
В разделе 1.1 вывод типа шаблона пояснялся с использованием обобщенного шаблона функции
>template
>void f(ParamType param);
и обобщенного вызова
>f(expr); // Вызов f с некоторым выражением
При вызове >f
компиляторы используют >expr
для вывода типов >T
и >ParamType
.
Когда переменная объявлена с использованием ключевого слова >auto
, оно играет роль >Т
в шаблоне, а спецификатор типа переменной действует как >ParamType
. Это проще показать, чем описать, так что рассмотрим следующий пример: