246 lines
12 KiB
Markdown
246 lines
12 KiB
Markdown
[over.ics.rank]
|
||
|
||
# 12 Overloading [[over]](./#over)
|
||
|
||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.rank)
|
||
|
||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.rank)
|
||
|
||
#### 12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2706)
|
||
|
||
This subclause defines a partial ordering of implicit conversion
|
||
sequences based on the relationships[*better conversion sequence*](#def:conversion_sequence,better "12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]") and[*better conversion*](#def:conversion,better "12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]")[.](#1.sentence-1)
|
||
|
||
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*](#def:conversion_sequence,worse "12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]") than S1[.](#1.sentence-2)
|
||
|
||
If conversion sequence S1 is neither better
|
||
than nor worse than conversion sequence S2, S1 and S2 are said to
|
||
be[*indistinguishable conversion sequences*](#def:conversion_sequence,indistinguishable "12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]")[.](#1.sentence-3)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2722)
|
||
|
||
When comparing the basic forms of implicit conversion sequences
|
||
(as defined in [[over.best.ics]](over.best.ics "12.2.4.2 Implicit conversion sequences"))
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
a [standard conversion sequence](over.ics.scs "12.2.4.2.2 Standard conversion sequences [over.ics.scs]") is a better
|
||
conversion sequence than a user-defined conversion sequence
|
||
or an ellipsis conversion sequence, and
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
a [user-defined conversion sequence](over.ics.user "12.2.4.2.3 User-defined conversion sequences [over.ics.user]") is a
|
||
better conversion sequence than an [ellipsis conversion
|
||
sequence](over.ics.ellipsis "12.2.4.2.4 Ellipsis conversion sequences [over.ics.ellipsis]")[.](#2.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2736)
|
||
|
||
Two implicit conversion sequences of the same form are
|
||
indistinguishable conversion sequences unless one of the
|
||
following rules applies:
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
List-initialization sequence L1 is a better conversion sequence than
|
||
list-initialization sequence L2 if
|
||
* [(3.1.1)](#3.1.1)
|
||
|
||
L1 converts to std::initializer_list<X> for some X andL2 does not, or, if not that,
|
||
|
||
* [(3.1.2)](#3.1.2)
|
||
|
||
L1 and L2 convert to arrays of the same element type, and
|
||
either the number of elements n1 initialized by L1 is less than the number of elements n2 initialized by L2, orn1=n2 andL2 converts to an array of unknown bound and L1 does not,
|
||
|
||
even if one of the other rules in this paragraph would otherwise apply[.](#3.1.sentence-1)
|
||
[*Example [1](#example-1)*: void f1(int); // #1void f1(std::initializer_list<long>); // #2void g1() { f1({42}); } // chooses #2void f2(std::pair<const char*, const char*>); // #3void f2(std::initializer_list<std::string>); // #4void g2() { f2({"foo","bar"}); } // chooses #4 â *end example*]
|
||
[*Example [2](#example-2)*: void f(int (&&)[] ); // #1void f(double (&&)[] ); // #2void f(int (&&)[2]); // #3 f( {1} ); // Calls #1: Better than #2 due to conversion, better than #3 due to bounds f( {1.0} ); // Calls #2: Identity conversion is better than floating-integral conversion f( {1.0, 2.0} ); // Calls #2: Identity conversion is better than floating-integral conversion f( {1, 2} ); // Calls #3: Converting to array of known bound is better than to unknown bound,// and an identity conversion is better than floating-integral conversion â *end example*]
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
Standard conversion sequenceS1 is a better conversion
|
||
sequence than standard conversion sequenceS2 if
|
||
* [(3.2.1)](#3.2.1)
|
||
|
||
S1 is a proper subsequence ofS2 (comparing the conversion sequences in the canonical form defined
|
||
by [[over.ics.scs]](over.ics.scs "12.2.4.2.2 Standard conversion sequences"), excluding any Lvalue Transformation;
|
||
the identity conversion sequence is considered to be a
|
||
subsequence of any non-identity conversion sequence)
|
||
or, if not that,
|
||
|
||
* [(3.2.2)](#3.2.2)
|
||
|
||
the rank ofS1 is better than the rank ofS2,
|
||
orS1 andS2 have the same rank and are distinguishable by the rules
|
||
in the paragraph below,
|
||
or, if not that,
|
||
|
||
* [(3.2.3)](#3.2.3)
|
||
|
||
S1 and S2 include reference bindings ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")) and
|
||
neither refers to an implicit object parameter of a non-static member function
|
||
declared without a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]"),
|
||
and S1 binds an rvalue reference to an
|
||
rvalue and S2 binds an lvalue reference
|
||
[*Example [3](#example-3)*: 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,
|
||
|
||
* [(3.2.4)](#3.2.4)
|
||
|
||
S1 and S2 include reference bindings ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")) andS1 binds an lvalue reference to an lvalue of function type andS2 binds an rvalue reference to an lvalue of function type
|
||
[*Example [4](#example-4)*: int f(void(&)()); // #1int f(void(&&)()); // #2void g();int i1 = f(g); // calls #1 â *end example*]
|
||
or, if not that,
|
||
|
||
* [(3.2.5)](#3.2.5)
|
||
|
||
S1 and S2 differ only
|
||
in their qualification conversion ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) and
|
||
yield similar types T1 and T2, respectively
|
||
(where a standard conversion sequence that is a reference binding
|
||
is considered to yield the cv-unqualified referenced type),
|
||
where T1 and T2 are not the same type, andconst T2 is reference-compatible with T1 ([[dcl.init.ref]](dcl.init.ref "9.5.4 References"))
|
||
[*Example [5](#example-5)*: int f(const volatile int *);int f(const int *);int i;int j = f(&i); // calls f(const int*)int g(const int*);int g(const volatile int* const&);int* p;int k = g(p); // calls g(const int*) â *end example*]
|
||
or, if not that,
|
||
|
||
* [(3.2.6)](#3.2.6)
|
||
|
||
S1 andS2 bind âreference to T1â and âreference to T2â,
|
||
respectively ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")),
|
||
where T1 and T2 are not the same type, andT2 is reference-compatible with T1
|
||
[*Example [6](#example-6)*: 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); // ambiguousstruct X {void f() const; void f();};void g(const X& a, X b) { a.f(); // calls X::f() const b.f(); // calls X::f()}int h(int (&)[]);int h(int (&)[1]);void g2() {int a[1];
|
||
h(a); // calls h(int (&)[1])} â *end example*]
|
||
or, if not that,
|
||
|
||
* [(3.2.7)](#3.2.7)
|
||
|
||
S1 and S2 bind the same reference type âreference to Tâ and
|
||
have source types V1 and V2, respectively,
|
||
where the standard conversion sequence from V1* to T* is better than the standard conversion sequence from V2* to T*[.](#3.2.sentence-1)
|
||
[*Example [7](#example-7)*: struct Z {};
|
||
|
||
struct A {operator Z&(); operator const Z&(); // #1};
|
||
|
||
struct B {operator Z(); operator const Z&&(); // #2};
|
||
|
||
const Z& r1 = A(); // OK, uses #1const Z&& r2 = B(); // OK, uses #2 â *end example*]
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
User-defined conversion sequenceU1 is a better conversion sequence than another user-defined conversion
|
||
sequenceU2 if they contain the same user-defined conversion function or
|
||
constructor or they initialize the same class in an aggregate
|
||
initialization and in either case the second standard conversion
|
||
sequence ofU1 is better than
|
||
the second standard conversion sequence ofU2[.](#3.3.sentence-1)
|
||
[*Example [8](#example-8)*: 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*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2973)
|
||
|
||
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[.](#4.sentence-1)
|
||
|
||
Two conversion sequences with the same rank are indistinguishable unless
|
||
one of the following rules applies:
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
A conversion that does not convert a pointer or a pointer to member
|
||
tobool is better than one that does[.](#4.1.sentence-1)
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
A conversion that promotes an enumeration whose underlying type is fixed to its underlying
|
||
type is better than one that promotes to the promoted underlying type, if the two are
|
||
different[.](#4.2.sentence-1)
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
A conversion in either direction
|
||
between floating-point type FP1 and floating-point type FP2 is better than a conversion in the same direction
|
||
between FP1 and arithmetic type T3 if
|
||
* [(4.3.1)](#4.3.1)
|
||
|
||
the floating-point conversion rank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) of FP1 is equal to the rank of FP2, and
|
||
|
||
* [(4.3.2)](#4.3.2)
|
||
|
||
T3 is not a floating-point type, orT3 is a floating-point type
|
||
whose rank is not equal to the rank of FP1, or
|
||
the floating-point conversion subrank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) of FP2 is greater than the subrank of T3[.](#4.3.sentence-1)
|
||
[*Example [9](#example-9)*: int f(std::float32_t);int f(std::float64_t);int f(long long);float x;
|
||
std::float16_t y;int i = f(x); // calls f(std::float32_t) on implementations where// float and std::float32_t have equal conversion ranksint j = f(y); // error: ambiguous, no equal conversion rank â *end example*]
|
||
|
||
- [(4.4)](#4.4)
|
||
|
||
If classB is derived directly or indirectly from classA,
|
||
conversion ofB* toA* is better than conversion ofB* tovoid*,
|
||
and conversion ofA* tovoid* is better than conversion
|
||
ofB* tovoid*[.](#4.4.sentence-1)
|
||
|
||
- [(4.5)](#4.5)
|
||
|
||
If classB is derived directly or indirectly from classA and classC is derived directly or indirectly fromB,
|
||
* [(4.5.1)](#4.5.1)
|
||
|
||
conversion ofC* toB* is better than conversion ofC* toA*,
|
||
[*Example [10](#example-10)*: 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*]
|
||
|
||
* [(4.5.2)](#4.5.2)
|
||
|
||
binding of an expression of typeC to a reference to typeB is better than binding an expression of typeC to a reference to typeA,
|
||
|
||
* [(4.5.3)](#4.5.3)
|
||
|
||
conversion ofA::* toB::* is better than conversion ofA::* toC::*,
|
||
|
||
* [(4.5.4)](#4.5.4)
|
||
|
||
conversion ofC toB is better than conversion ofC toA,
|
||
|
||
* [(4.5.5)](#4.5.5)
|
||
|
||
conversion ofB* toA* is better than conversion ofC* toA*,
|
||
|
||
* [(4.5.6)](#4.5.6)
|
||
|
||
binding of an expression of typeB to a reference to typeA is better than binding an expression of typeC to a
|
||
reference to typeA,
|
||
|
||
* [(4.5.7)](#4.5.7)
|
||
|
||
conversion ofB::* toC::* is better than conversion
|
||
ofA::* toC::*,
|
||
and
|
||
|
||
* [(4.5.8)](#4.5.8)
|
||
|
||
conversion ofB toA is better than conversion ofC toA[.](#4.5.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
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]](over.match.best "12.2.4 Best viable function")); in
|
||
all other contexts, the source types will be the same and the target
|
||
types will be different[.](#4.5.sentence-2)
|
||
â *end note*]
|