Given these definitions,
a viable function
F1 is defined to be a
better
function than another viable function
F2
if for all arguments
i,
ICSi(F1) is not a worse conversion
sequence than
ICSi(F2), and then
- for some argument j,
ICSj(F1) is a better conversion sequence than
ICSj(F2), or, if not that,
- the context is an initialization by user-defined conversion
(see [dcl.init],
[over.match.conv], and [over.match.ref])
and the standard conversion sequence
from the return type of F1 to the destination type
(i.e., the type of the entity being initialized)
is a better conversion sequence than the standard conversion sequence
from the return type of F2 to the destination type
[
Example 1:
struct A {
A();
operator int();
operator double();
} a;
int i = a;
float x = a;
—
end example]
or, if not that, - the context is an initialization by conversion function for direct
reference binding of a reference to function type, the
return type of F1 is the same kind of reference (lvalue or rvalue)
as the reference being initialized, and the return type of F2 is not
[
Example 2:
template <class T> struct A {
operator T&();
operator T&&();
};
typedef int Fn();
A<Fn> a;
Fn& lf = a;
Fn&& rf = a;
—
end example]
or, if not that, - F1
is not a function template specialization and
F2
is a
function template
specialization, or, if not that,
- F1
and
F2
are
function template specializations,
and the function template
for
F1
is more specialized than the template for
F2
according to the partial ordering rules described in [temp.func.order],
or, if not that,
- F1 and F2 are non-template functions with the same
parameter-type-lists, and F1 is more constrained than F2
according to the partial ordering of constraints described in
[temp.constr.order], or if not that,
- F1 is a constructor for a class D,
F2 is a constructor for a base class B of D, and
for all arguments
the corresponding parameters of F1 and F2 have the same type
[
Example 3:
struct A {
A(int = 0);
};
struct B: A {
using A::A;
B();
};
int main() {
B b;
}
—
end example]
or, if not that, - F2 is a rewritten candidate ([over.match.oper]) and
F1 is not
[
Example 4:
struct S {
friend auto operator<=>(const S&, const S&) = default;
friend bool operator<(const S&, const S&);
};
bool b = S() < S();
—
end example]
or, if not that, - F1 and F2 are rewritten candidates, and
F2 is a synthesized candidate
with reversed order of parameters
and F1 is not
[
Example 5:
struct S {
friend std::weak_ordering operator<=>(const S&, int);
friend std::weak_ordering operator<=>(int, const S&);
};
bool b = 1 < S();
—
end example]
or, if not that - F1 is generated from a
deduction-guide ([over.match.class.deduct])
and F2 is not, or, if not that,
- F1 is the copy deduction candidate
and F2 is not, or, if not that,
- F1 is generated from a non-template constructor
and F2 is generated from a constructor template.
[
Example 6:
template <class T> struct A {
using value_type = T;
A(value_type);
A(const A&);
A(T, T, int);
template<class U>
A(int, T, U);
};
A x(1, 2, 3);
template <class T>
A(T) -> A<T>;
A a(42);
A b = a;
template <class T>
A(A<T>) -> A<A<T>>;
A b2 = a;
—
end example]