12 Overloading [over]

12.2 Overload resolution [over.match]

12.2.3 Viable functions [over.match.viable]

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.
First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list.
  • If there are m arguments in the list, all candidate functions having exactly m parameters are viable.
  • A candidate function having fewer than m parameters is viable only if it has an ellipsis in its parameter list ([dcl.fct]).
    For the purposes of overload resolution, any argument for which there is no corresponding parameter is considered to “match the ellipsis” ([over.ics.ellipsis]).
  • A candidate function C having more than m parameters is viable only if the set of scopes G, as defined below, is not empty.
    G consists of every scope X that satisfies all of the following:
    • There is a declaration of C, whose host scope is X, considered by the overload resolution.
    • For every parameter P where k > m, there is a reachable declaration, whose host scope is X, that specifies a default argument ([dcl.fct.default]) for P.
    If C is selected as the best viable function ([over.match.best]):
    • G shall contain exactly one scope (call it S).
    • If the candidates are denoted by a splice-expression, then S shall not be a block scope.
    • The default arguments used in the call to C are the default arguments specified by the reachable declarations whose host scope is S.
    For the purposes of overload resolution, the parameter list is truncated on the right, so that there are exactly m parameters.
[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]).