[over.ics.rank] defines a partial ordering of implicit conversion sequences based on the relationships better conversion sequence and better conversion. If an implicit conversion sequence S1 is defined by these rules to be a better conversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1. If conversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said to be indistinguishable conversion sequences.
When comparing the basic forms of implicit conversion sequences (as defined in [over.best.ics])
a standard conversion sequence ([over.ics.scs]) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
a user-defined conversion sequence ([over.ics.user]) is a better conversion sequence than an ellipsis conversion sequence ([over.ics.ellipsis]).
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that,
the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below, or, if not that,
S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 ([conv.qual]), respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualification signature of type T2. [ Example:
int f(const int *);
int f(int *);
int i;
int j = f(&i); // calls f(int*)
— end example ] or, if not that,
S1 and S2 are reference bindings ([dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.
[ Example:
int i; int f1(); int&& f2(); int g(const int&); int g(const int&&); int j = g(i); // calls g(const int&) int k = g(f1()); // calls g(const int&&) int l = g(f2()); // calls g(const int&&) struct A { A& operator<<(int); void p() &; void p() &&; }; A& operator<<(A&&, char); A() << 1; // calls A::operator<<(int) A() << 'c'; // calls operator<<(A&&, char) A a; a << 1; // calls A::operator<<(int) a << 'c'; // calls A::operator<<(int) A().p(); // calls A::p()&& a.p(); // calls A::p()&
— end example ] or, if not that,
S1 and S2 are reference bindings ([dcl.init.ref]) and S1 binds an lvalue reference to a function lvalue and S2 binds an rvalue reference to a function lvalue. [ Example:
template<class T> int f(T&);
template<class T> int f(T&&);
void g();
int i1 = f(g); // calls f(T&)
— end example ]
S1 and S2 are reference bindings ([dcl.init.ref]), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers. [ Example:
int f(const int &); int f(int &); int g(const int &); int g(int); int i; int j = f(i); // calls f(int &) int k = g(i); // ambiguous struct X { void f() const; void f(); }; void g(const X& a, X b) { a.f(); // calls X::f() const b.f(); // calls X::f() }
— end example ]
User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or aggregate initialization and the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2. [ Example:
struct A { operator short(); } a; int f(int); int f(float); int i = f(a); // calls f(int), because short → int is // better than short → float.
— end example ]
List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1 converts to std::initializer_list<X> for some X and L2 does not.
Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:
A conversion that does not convert a pointer, a pointer to member, or std::nullptr_t to bool is better than one that does.
If class B is derived directly or indirectly from class A, conversion of B* to A* is better than conversion of B* to void*, and conversion of A* to void* is better than conversion of B* to void*.
If class B is derived directly or indirectly from class A and class C is derived directly or indirectly from B,
conversion of C* to B* is better than conversion of C* to A*, [ Example:
struct A {};
struct B : public A {};
struct C : public B {};
C *pc;
int f(A *);
int f(B *);
int i = f(pc); // calls f(B*)
— end example ]
binding of an expression of type C to a reference of type B& is better than binding an expression of type C to a reference of type A&,
conversion of A::* to B::* is better than conversion of A::* to C::*,
conversion of C to B is better than conversion of C to A,
conversion of B* to A* is better than conversion of C* to A*,
binding of an expression of type B to a reference of type A& is better than binding an expression of type C to a reference of type A&,
conversion of B::* to C::* is better than conversion of A::* to C::*, and
conversion of B to A is better than conversion of C to A.
[ Note: Compared conversion sequences will have different source types only in the context of comparing the second standard conversion sequence of an initialization by user-defined conversion (see [over.match.best]); in all other contexts, the source types will be the same and the target types will be different. — end note ]