А.7. Автоматическое выведение типа переменной

С++ — статически типизированный язык: тип любой переменной известен на этапе компиляции. Более того, программист обязан указать тип каждой переменной. В некоторых случаях имена оказываются очень громоздкими, например:

std::map<std::string, std::unique_ptr<some_data>> m;

std::map<std::string, std::unique_ptr<some_data>>::iterator

iter = m.find("my key");

Традиционно для решения этой проблемы использовались псевдонимы типов (typedef), позволяющие сократить длину идентификатора типа и избавиться от потенциальных проблем несовместимости типов. Этот способ работает и в C++11, но появился и новый: если переменная инициализируется в объявлении, то в качестве ее типа можно указать auto. Тогда компилятор автоматически выведет тип переменной из типа инициализатора. Следовательно, приведенный выше пример итератора можно записать и так:

auto iter = m.find("my key");

Спецификатор auto необязательно употреблять изолированно; его можно использовать в сочетании с другими спецификаторами для объявления const-переменных, а также указателей и ссылок. Вот несколько примеров объявления переменных с помощью auto и дополнительных конструкций:

auto i = 42;        // int

auto& j = i;        // int&

auto const k = i;   // int const

auto* const p = &i; // int * const

Правила выведения типа переменной основаны на правилах, применяемых в другом месте языка, где выводятся типы: параметры шаблонов функций. В объявлении вида

Какое-то-типовое-выражение-включающее-auto

var = some-expression;

переменная var имеет тот же тип, который был бы выведен, если бы она встречалась в качестве параметра шаблона функции, объявленного с таким же типовым выражением, только auto заменяется именем типового параметра шаблона:

template<typename T>

void f(type-expression var);

f(some-expression);

Это означает, что тип массива сводится к указателю, а ссылки опускаются, если только в типовом выражении переменная явно не объявлена как ссылка. Например:

int some_array[45];

auto p = some_array; // int*

int& r = *p;

auto x = r;          // int

auto& y = r;         // int&

Это позволяет существенно упростить объявление переменных, особенно в случаях, когда полный идентификатор типа очень длинный или даже неизвестен (например, тип результата вызова функции в шаблоне).