[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}template<typename... Ts>int k(int = 3, Ts...);int i = k<int>(); // 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)
