10 Declarations [dcl.dcl]

10.1 Specifiers [dcl.spec]

10.1.7 Type specifiers [dcl.type]

10.1.7.4 The auto specifier [dcl.spec.auto]

10.1.7.4.1 Placeholder type deduction [dcl.type.auto.deduct]

Placeholder type deduction - это процесс, с помощью которого тип, содержащий тип-заполнитель, заменяется выведенным типом.

Тип, T содержащий тип заполнителя и соответствующий инициализатор e, определяются следующим образом:

  • для неотброшенного return оператора, который встречается в функции, объявленной с возвращаемым типом, который содержит тип-заполнитель, T является объявленным возвращаемым типом и e является операндом return оператора. Если у return оператора нет операнда, то e есть void();

  • для переменной, объявленной с типом, содержащим тип-заполнитель, T является объявленным типом переменной и e инициализатором. Если инициализация - это инициализация с прямым списком, инициализатор должен braced-init-list содержать только один элемент assignment-expression и e является assignment-expression;

  • для параметра шаблона, не являющегося типом, объявленного с типом, содержащим тип-заполнитель, T является объявленным типом параметра шаблона, не являющимся типом, и e является соответствующим аргументом шаблона.

В случае return заявления, без операнда или с операндом типа void, T должны быть либо decltype(auto) или cv auto.

Если вывод предназначен для return оператора и e представляет собой braced-init-list([dcl.init.list]), программа сформирована неправильно.

Если заполнитель - это , замена выведенного типа определяется с использованием правил вывода аргументов шаблона. Получить от путем замены вхождений либо на новый параметр шаблона изобретенного типа, либо, если инициализация - инициализация списка-копирования, на . Выведите значение для использования правил , где - тип параметра шаблона функции, а соответствующий аргумент - . Если вычет не удается, декларация имеет неверный формат. В противном случае получается заменой выведенного на . [ auto type-specifierT' T P T auto U std​::​initializer_­list<U> U template argument deduction from a function call P e T' U PExample:

auto x1 = { 1, 2 };             // decltype(x1) is std​::​initializer_­list<int>
auto x2 = { 1, 2.0 };           // error: cannot deduce element type
auto x3{ 1, 2 };                // error: not a single element
auto x4 = { 3 };                // decltype(x4) is std​::​initializer_­list<int>
auto x5{ 3 };                   // decltype(x5) is int

end example]

[Example:

const auto &i = expr;

Тип i - это выведенный тип параметра u при вызове f(expr) следующего шаблона придуманной функции:

template <class U> void f(const U& u);

end example]

Если заполнителем является , должен быть только заполнитель. Тип, выведенный для , определяется, как описано в , как если бы он был операндом . [ decltype(auto) type-specifierT T [dcl.type.simple]e decltypeExample:

int i;
int&& f();
auto           x2a(i);          // decltype(x2a) is int
decltype(auto) x2d(i);          // decltype(x2d) is int
auto           x3a = i;         // decltype(x3a) is int
decltype(auto) x3d = i;         // decltype(x3d) is int
auto           x4a = (i);       // decltype(x4a) is int
decltype(auto) x4d = (i);       // decltype(x4d) is int&
auto           x5a = f();       // decltype(x5a) is int
decltype(auto) x5d = f();       // decltype(x5d) is int&&
auto           x6a = { 1, 2 };  // decltype(x6a) is std​::​initializer_­list<int>
decltype(auto) x6d = { 1, 2 };  // error, { 1, 2 } is not an expression
auto          *x7a = &i;        // decltype(x7a) is int*
decltype(auto)*x7d = &i;        // error, declared type is not plain decltype(auto)

end example]