#
From the set of candidate functions constructed for a given context ([over.match.funcs]), a set of viable functions is chosen, from which the best function will be selected by comparing argument conversion sequences and associated constraints ([temp.constr.decl]) for the best fit ([over.match.best]).
The selection of viable functions considers associated constraints, if any, and relationships between arguments and function parameters other than the ranking of conversion sequences.
2
#
First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list.
[Example 1: namespace A { extern "C" void f(int, int = 5); extern "C" void f(int = 6, int); } namespace B { extern "C" void f(int, int = 7); } void use() { [:^A::f:](3, 4); / OK, default argument was not used for viability [:^A::f:](3); / error: default argument provided by declarations from two scopes [:^A::f:](); / OK, default arguments provided by declarations in the scope of A using A::f; using B::f; f(3, 4); / OK, default argument was not used for viability f(3); / error: default argument provided by declaration from two scopes f(); / OK, default arguments provided by declarations in the scope of A void g(int = 8); g(); / OK [:^g:](); / error: host scope is block scope } void h(int = 7); constexpr std::meta::info r = ^^h; void poison() { void h(int = 8); h(); / OK, calls h(8) [:^h:](); / error: default argument provided by declarations from two scopes } void call_h() { [:^h:](); / error: default argument provided by declarations from two scopes [:r:](); / error: default argument provided by declarations from two scopes } template<typename. Ts> int k(int = 3, Ts..); int i = k<int>(); / error: no default argument for the second parameter int j = k<>(); / OK — end example]
Second, for a function to be viable, if it has associated constraints ([temp.constr.decl]), those constraints shall be satisfied ([temp.constr.constr]).
Third, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F.
If the parameter has reference type, the implicit conversion sequence includes the operation of binding the reference, and the fact that an lvalue reference to non-const cannot bind to an rvalue and that an rvalue reference cannot bind to an lvalue can affect the viability of the function (see [over.ics.ref]).

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