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 P Example:
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 decltype Example:
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 ]