[over.match.viable] # 12 Overloading [[over]](./#over) ## 12.2 Overload resolution [[over.match]](over.match#viable) ### 12.2.3 Viable functions [over.match.viable] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1683) From the set of candidate functions constructed for a given context ([[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists")), 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]](temp.constr.decl "13.5.3 Constrained declarations")) for the best fit ([[over.match.best]](over.match.best "12.2.4 Best viable function"))[.](#1.sentence-1) The selection of viable functions considers associated constraints, if any, and relationships between arguments and function parameters other than the ranking of conversion sequences[.](#1.sentence-2) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1695) First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list[.](#2.sentence-1) - [(2.1)](#2.1) If there are m arguments in the list, all candidate functions having exactly m parameters are viable[.](#2.1.sentence-1) - [(2.2)](#2.2) A candidate function having fewer than m parameters is viable only if it has an ellipsis in its parameter list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#2.2.sentence-1) For the purposes of overload resolution, any argument for which there is no corresponding parameter is considered to “match the ellipsis” ([[over.ics.ellipsis]](over.ics.ellipsis "12.2.4.2.4 Ellipsis conversion sequences"))[.](#2.2.sentence-2) - [(2.3)](#2.3) A candidate function C having more than m parameters is viable only if the set of scopes G, as defined below, is not empty[.](#2.3.sentence-1) G consists of every scope X that satisfies all of the following: * [(2.3.1)](#2.3.1) There is a declaration of C, whose host scope is X, considered by the overload resolution[.](#2.3.1.sentence-1) * [(2.3.2)](#2.3.2) For every kth parameter P where k > m, there is a reachable declaration, whose host scope is X, that specifies a default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")) for P[.](#2.3.2.sentence-1) If C is selected as the best viable function ([[over.match.best]](over.match.best "12.2.4 Best viable function")): * [(2.3.3)](#2.3.3) G shall contain exactly one scope (call it S)[.](#2.3.3.sentence-1) * [(2.3.4)](#2.3.4) If the candidates are denoted by a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]"), then S shall not be a block scope[.](#2.3.4.sentence-1) * [(2.3.5)](#2.3.5) The default arguments used in the call to C are the default arguments specified by the reachable declarations whose host scope is S[.](#2.3.5.sentence-1) For the purposes of overload resolution, the parameter list is truncated on the right, so that there are exactly m parameters[.](#2.3.sentence-4) [*Example [1](#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 Ausing 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 Avoid 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}templateint k(int = 3, Ts...);int i = k(); // error: no default argument for the second parameterint j = k<>(); // OK — *end example*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1784) Second, for a function to be viable, if it has associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")), those constraints shall be satisfied ([[temp.constr.constr]](temp.constr.constr "13.5.2 Constraints"))[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1788) Third, forF to be a viable function, there shall exist for each argument an[implicit conversion sequence](over.best.ics#def:conversion_sequence,implicit "12.2.4.2 Implicit conversion sequences [over.best.ics]") that converts that argument to the corresponding parameter ofF[.](#4.sentence-1) 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]](over.ics.ref "12.2.4.2.5 Reference binding"))[.](#4.sentence-2)