Читать «Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14» онлайн - страница 18
Скотт Мейерс
const auto& rx = x;
спецификатором типа является const auto&
. Для вывода типов для x
, сх
и rx
в приведенных примерах компилятор действует так, как если бы для каждого объявления имелся шаблон, а также вызов этого шаблона с соответствующим инициализирующим выражением:
template<typename Т> // Концептуальный шаблон для
void func_for_x(Т param); // вывода типа x
func_for_x(27); // Концептуальный вызов: выве-
// денный тип param является
// типом x
template<typename Т> // Концептуальный шаблон для
void func_for_cx(const Т param); // вывода типа cx
func_for_cx(x); // Концептуальный вызов: выве-
// денный тип param является
// типом cx
template<typename Т> // Концептуальный шаблон для
void func_for_rx(const T& param); // вывода типа rx
func_for_rx(x); // Концептуальный вызов: выве-
// денный тип param является
// типом rx
Как я уже говорил, вывод типов для auto
представляет собой (с одним исключением, которое мы вскоре рассмотрим) то же самое, что и вывод типов для шаблонов.
В разделе 1.1 вывод типов шаблонов был разделен на три случая, основанных на характеристиках ParamType
, спецификаторе типа param
в обобщенном шаблоне функции. В объявлении переменной с использованием auto
спецификатор типа занимает место ParamType
, так что у нас опять имеются три случая.
• Случай 1. Спецификатор типа представляет собой ссылку или указатель, но не универсальную ссылку.
• Случай 2. Спецификатор типа представляет собой универсальную ссылку.
• Случай 3. Спецификатор типа не является ни ссылкой, ни указателем. Мы уже встречались со случаями 1 и 3:
auto x = 27; // Случай 3 (x не указатель и не ссылка)
const auto cx = x; // Случай 3 (cx не указатель и не ссылка)
const auto& rx = x; // Случай 1 (rx - неуниверсальная ссылка)
Случай 2 работает, как и ожидалось:
auto&& uref1 = x; // x - int и lvalue, так что тип uref1 – int&
auto&& uref2 = cx; // cx - const int и lvalue, так что тип
// uref2 - const int&
auto&& uref3 = 27; // 27 - int и rvalue, так что тип
// uref3 - int&&
Раздел 1.1 завершился обсуждением того, как имена массивов и функций превращаются в указатели для спецификаторов типа, не являющихся ссылками. То же самое происходит и при выводе типа auto
:
const char name[] = // Тип name - const char [13]
"R. N. Briggs";
auto arr1 = name; // Тип arr1 - const char*
auto& arr2 = name; // Тип arr2 - const char (&)[13]
void someFunc(int, double); // someFunc - функция, ее тип
// void(int, double)
auto func1 = someFunc; // Тип func1 - void (*)(int, double)
auto& func2 = someFunc; // Тип func2 - void (&)(int, double)