#
Placeholder type deduction is the process by which a type containing a placeholder type is replaced by a deduced type.
2
#
A type T containing a placeholder type, and a corresponding initializer-clause E, are determined as follows:
T shall not be an array type.
If the placeholder-type-specifier is of the form type-constraint
If the initialization is copy-list-initialization, a declaration of std​::​initializer_list shall precede ([basic.lookup.general]) the placeholder-type-specifier.
Obtain P from T by replacing the occurrence of type-constraint
If E is a value synthesized for a constant template parameter of type decltype(auto) ([temp.func.order]), the declaration is ill-formed.
Otherwise, deduce a value for U using the rules of template argument deduction from a function call ([temp.deduct.call]), where P is a function template parameter type and the corresponding argument is E.
If the deduction fails, the declaration is ill-formed.
Otherwise,
[Example 1: 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 2: const auto &i = expr;
The type of i is the deduced type of the parameter u in the call f(expr) of the following invented function template: template <class U> void f(const U& u);
— end example]
If the placeholder-type-specifier is of the form type-constraint
The type deduced for T is determined as described in [dcl.type.decltype], as though E had been the operand of the decltype.
[Example 3: 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) auto f1(int x) -> decltype(x)) { return (x); } / return type is int& auto f2(int x) -> decltype(auto) { return (x); } / return type is int&& — end example]
For a placeholder-type-specifier with a type-constraint, the immediately-declared constraint ([temp.param]) of the type-constraint for the type deduced for the placeholder shall be satisfied.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant