1090 lines
55 KiB
Markdown
1090 lines
55 KiB
Markdown
[over.match.best]
|
||
|
||
# 12 Overloading [[over]](./#over)
|
||
|
||
## 12.2 Overload resolution [[over.match]](over.match#best)
|
||
|
||
### 12.2.4 Best viable function [over.match.best]
|
||
|
||
#### [12.2.4.1](#general) General [[over.match.best.general]](over.match.best.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1808)
|
||
|
||
Define ICSi(F) as
|
||
the implicit conversion sequence that converts
|
||
the ith argument in the list to the type of
|
||
the ith parameter of viable function F[.](#general-1.sentence-1)
|
||
|
||
[[over.best.ics]](#over.best.ics "12.2.4.2 Implicit conversion sequences") defines the implicit conversion sequences and [[over.ics.rank]](#over.ics.rank "12.2.4.3 Ranking implicit conversion sequences") defines what it means for one implicit conversion sequence to be
|
||
a better conversion sequence or worse conversion sequence than
|
||
another[.](#general-1.sentence-2)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1819)
|
||
|
||
Given these definitions,
|
||
a viable function F1 is defined to be a[*better*](#def:overloading,resolution,better_viable_function "12.2.4.1 General [over.match.best.general]") function than another viable function F2 if for all arguments i,ICSi(F1) is not a worse conversion
|
||
sequence than ICSi(F2), and then
|
||
|
||
- [(2.1)](#general-2.1)
|
||
|
||
for some argument j,ICSj(F1) is a better conversion sequence thanICSj(F2), or, if not that,
|
||
|
||
- [(2.2)](#general-2.2)
|
||
|
||
the context is an initialization by user-defined conversion
|
||
(see [[dcl.init]](dcl.init "9.5 Initializers"),[[over.match.conv]](over.match.conv "12.2.2.6 Initialization by conversion function"), and [[over.match.ref]](over.match.ref "12.2.2.7 Initialization by conversion function for direct reference binding"))
|
||
and the standard conversion sequence
|
||
from the result 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 result of F2 to the destination type
|
||
[*Example [1](#general-example-1)*: struct A { A(); operator int(); operator double();} a;int i = a; // a.operator int() followed by no conversion is better than// a.operator double() followed by a conversion to intfloat x = a; // ambiguous: both possibilities require conversions,// and neither is better than the other â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.3)](#general-2.3)
|
||
|
||
the context is an initialization by conversion function for [direct
|
||
reference binding](over.match.ref "12.2.2.7 Initialization by conversion function for direct reference binding [over.match.ref]") 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](#general-example-2)*: template <class T> struct A {operator T&(); // #1operator T&&(); // #2};typedef int Fn();
|
||
A<Fn> a;
|
||
Fn& lf = a; // calls #1 Fn&& rf = a; // calls #2 â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.4)](#general-2.4)
|
||
|
||
F1 is not a function template specialization andF2 is a
|
||
function template
|
||
specialization, or, if not that,
|
||
|
||
- [(2.5)](#general-2.5)
|
||
|
||
F1 andF2 are
|
||
function template specializations,
|
||
and the function template
|
||
forF1 is more specialized than the template forF2 according to the partial ordering rules described in [[temp.func.order]](temp.func.order "13.7.7.3 Partial ordering of function templates"),
|
||
or, if not that,
|
||
|
||
- [(2.6)](#general-2.6)
|
||
|
||
F1 and F2 are non-template functions andF1 is more partial-ordering-constrained thanF2 ([[temp.constr.order]](temp.constr.order "13.5.5 Partial ordering by constraints"))
|
||
[*Example [3](#general-example-3)*: template <typename T = int>struct S {constexpr void f(); // #1constexpr void f(this S&) requires true; // #2};
|
||
|
||
void test() { S<> s;
|
||
s.f(); // calls #2} â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.7)](#general-2.7)
|
||
|
||
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 [4](#general-example-4)*: struct A { A(int = 0);};
|
||
|
||
struct B: A {using A::A;
|
||
B();};
|
||
|
||
int main() { B b; // OK, B::B()} â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.8)](#general-2.8)
|
||
|
||
F2 is a rewritten candidate ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions")) andF1 is not
|
||
[*Example [5](#general-example-5)*: struct S {friend auto operator<=>(const S&, const S&) = default; // #1friend bool operator<(const S&, const S&); // #2};bool b = S() < S(); // calls #2 â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.9)](#general-2.9)
|
||
|
||
F1 and F2 are rewritten candidates, andF2 is a synthesized candidate
|
||
with reversed order of parameters
|
||
and F1 is not
|
||
[*Example [6](#general-example-6)*: struct S {friend std::weak_ordering operator<=>(const S&, int); // #1friend std::weak_ordering operator<=>(int, const S&); // #2};bool b = 1 < S(); // calls #2 â *end example*]
|
||
or, if not that,
|
||
|
||
- [(2.10)](#general-2.10)
|
||
|
||
F1 and F2 are generated
|
||
from class template argument deduction ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9 Class template argument deduction"))
|
||
for a class D, andF2 is generated
|
||
from inheriting constructors from a base class of D while F1 is not, and
|
||
for each explicit function argument,
|
||
the corresponding parameters of F1 and F2 are either both ellipses or have the same type,
|
||
or, if not that,
|
||
|
||
- [(2.11)](#general-2.11)
|
||
|
||
F1 is generated from a[*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]") ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9 Class template argument deduction"))
|
||
and F2 is not, or, if not that,
|
||
|
||
- [(2.12)](#general-2.12)
|
||
|
||
F1 is the [copy deduction candidate](over.match.class.deduct#def:copy_deduction_candidate "12.2.2.9 Class template argument deduction [over.match.class.deduct]") and F2 is not, or, if not that,
|
||
|
||
- [(2.13)](#general-2.13)
|
||
|
||
F1 is generated from a non-template constructor
|
||
and F2 is generated from a constructor template[.](#general-2.sentence-1)
|
||
[*Example [7](#general-example-7)*: template <class T> struct A {using value_type = T;
|
||
A(value_type); // #1 A(const A&); // #2 A(T, T, int); // #3template<class U> A(int, T, U); // #4// #5 is the copy deduction candidate, A(A)};
|
||
|
||
A x(1, 2, 3); // uses #3, generated from a non-template constructortemplate <class T> A(T) -> A<T>; // #6, less specialized than #5 A a(42); // uses #6 to deduce A<int> and #1 to initialize A b = a; // uses #5 to deduce A<int> and #2 to initializetemplate <class T> A(A<T>) -> A<A<T>>; // #7, as specialized as #5 A b2 = a; // uses #7 to deduce A<A<int>> and #1 to initialize â *end example*]
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2022)
|
||
|
||
If there is exactly one viable function that is a better function
|
||
than all other viable functions, then it is the one selected by
|
||
overload resolution; otherwise the call is ill-formed[.](#general-3.sentence-1)[105](#footnote-105 "The algorithm for selecting the best viable function is linear in the number of viable functions. Run a simple tournament to find a function W that is not worse than any opponent it faced. Although it is possible that another function F that W did not face is at least as good as W, F cannot be the best function because at some point in the tournament F encountered another function G such that F was not better than G. Hence, either W is the best function or there is no best function. So, make a second pass over the viable functions to verify that W is better than all other functions.")
|
||
|
||
[*Example [8](#general-example-8)*: void Fcn(const int*, short);void Fcn(int*, int);
|
||
|
||
int i;short s = 0;
|
||
|
||
void f() { Fcn(&i, s); // is ambiguous because &i â int* is better than &i â const int*// but s â short is also better than s â int Fcn(&i, 1L); // calls Fcn(int*, int), because &i â int* is better than &i â const int*// and 1L â short and 1L â int are indistinguishable Fcn(&i, 'c'); // calls Fcn(int*, int), because &i â int* is better than &i â const int*// and 'c' â int is better than 'c' â short} â *end example*]
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2083)
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
If the best viable function was made viable by one or more default arguments,
|
||
additional requirements apply ([[over.match.viable]](over.match.viable "12.2.3 Viable functions"))[.](#general-4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[105)](#footnote-105)[105)](#footnoteref-105)
|
||
|
||
The algorithm
|
||
for selecting the best viable function is linear in the number
|
||
of viable
|
||
functions[.](#footnote-105.sentence-1)
|
||
|
||
Run a simple tournament to find a functionW that is not
|
||
worse than any
|
||
opponent it faced[.](#footnote-105.sentence-2)
|
||
|
||
Although it is possible that another functionF thatW did not face
|
||
is at least as good asW,F cannot be the best function because at some point in the
|
||
tournamentF encountered another functionG such thatF was not better thanG[.](#footnote-105.sentence-3)
|
||
|
||
Hence,
|
||
either W is
|
||
the best function or there is no best function[.](#footnote-105.sentence-4)
|
||
|
||
So, make a second pass over
|
||
the viable
|
||
functions to verify thatW is better than all other functions[.](#footnote-105.sentence-5)
|
||
|
||
#### [12.2.4.2](#over.best.ics) Implicit conversion sequences [[over.best.ics]](over.best.ics)
|
||
|
||
#### [12.2.4.2.1](#over.best.ics.general) General [[over.best.ics.general]](over.best.ics.general)
|
||
|
||
[1](#over.best.ics.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2095)
|
||
|
||
An [*implicit conversion sequence*](#def:conversion_sequence,implicit "12.2.4.2.1 General [over.best.ics.general]") is a sequence of conversions used
|
||
to convert an argument in a function call to the type of the
|
||
corresponding parameter of the function being called[.](#over.best.ics.general-1.sentence-1)
|
||
|
||
The
|
||
sequence of conversions is an implicit conversion as defined in[[conv]](conv "7.3 Standard conversions"), which means it is governed by the rules for
|
||
initialization of an object or reference by a single
|
||
expression ([[dcl.init]](dcl.init "9.5 Initializers"), [[dcl.init.ref]](dcl.init.ref "9.5.4 References"))[.](#over.best.ics.general-1.sentence-2)
|
||
|
||
[2](#over.best.ics.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2106)
|
||
|
||
Implicit conversion sequences are concerned only with the type,
|
||
cv-qualification, and value category of the argument and how these
|
||
are converted to match the corresponding properties of the
|
||
parameter[.](#over.best.ics.general-2.sentence-1)
|
||
|
||
[*Note [1](#over.best.ics.general-note-1)*:
|
||
|
||
Other properties, such as the lifetime, storage duration, linkage,
|
||
alignment, accessibility of the argument, whether the argument is a bit-field,
|
||
and whether a function is [deleted](dcl.fct.def.delete "9.6.3 Deleted definitions [dcl.fct.def.delete]"), are ignored[.](#over.best.ics.general-2.sentence-2)
|
||
|
||
So, although an implicit
|
||
conversion sequence can be defined for a given argument-parameter
|
||
pair, the conversion from the argument to the parameter might still
|
||
be ill-formed in the final analysis[.](#over.best.ics.general-2.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[3](#over.best.ics.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2121)
|
||
|
||
A
|
||
well-formed implicit conversion
|
||
sequence is one of the following forms:
|
||
|
||
- [(3.1)](#over.best.ics.general-3.1)
|
||
|
||
a [standard conversion sequence](#over.ics.scs "12.2.4.2.2 Standard conversion sequences [over.ics.scs]"),
|
||
|
||
- [(3.2)](#over.best.ics.general-3.2)
|
||
|
||
a [user-defined conversion sequence](#over.ics.user "12.2.4.2.3 User-defined conversion sequences [over.ics.user]"), or
|
||
|
||
- [(3.3)](#over.best.ics.general-3.3)
|
||
|
||
an [ellipsis conversion sequence](#over.ics.ellipsis "12.2.4.2.4 Ellipsis conversion sequences [over.ics.ellipsis]")[.](#over.best.ics.general-3.sentence-1)
|
||
|
||
[4](#over.best.ics.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2134)
|
||
|
||
However, if the target is
|
||
|
||
- [(4.1)](#over.best.ics.general-4.1)
|
||
|
||
the first parameter of a constructor or
|
||
|
||
- [(4.2)](#over.best.ics.general-4.2)
|
||
|
||
the object parameter of a user-defined conversion function
|
||
|
||
and the constructor or user-defined conversion function is a candidate by
|
||
|
||
- [(4.3)](#over.best.ics.general-4.3)
|
||
|
||
[[over.match.ctor]](over.match.ctor "12.2.2.4 Initialization by constructor"), when the argument is the temporary in the second
|
||
step of a class copy-initialization,
|
||
|
||
- [(4.4)](#over.best.ics.general-4.4)
|
||
|
||
[[over.match.copy]](over.match.copy "12.2.2.5 Copy-initialization of class by user-defined conversion"), [[over.match.conv]](over.match.conv "12.2.2.6 Initialization by conversion function"), or [[over.match.ref]](over.match.ref "12.2.2.7 Initialization by conversion function for direct reference binding") (in all cases), or
|
||
|
||
- [(4.5)](#over.best.ics.general-4.5)
|
||
|
||
the second phase of [[over.match.list]](over.match.list "12.2.2.8 Initialization by list-initialization") when the initializer list has exactly one element that
|
||
is itself an initializer list, and
|
||
the target is the first parameter of a constructor of class X, and
|
||
the conversion is to X or reference to cv X,
|
||
|
||
user-defined conversion sequences are not considered[.](#over.best.ics.general-4.sentence-1)
|
||
|
||
[*Note [2](#over.best.ics.general-note-2)*:
|
||
|
||
These rules prevent more than one user-defined conversion from being
|
||
applied during overload resolution, thereby avoiding infinite recursion[.](#over.best.ics.general-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#over.best.ics.general-example-1)*: struct Y { Y(int); };struct A { operator int(); };
|
||
Y y1 = A(); // error: A::operator int() is not a candidatestruct X { X(); };struct B { operator X(); };
|
||
B b;
|
||
X x{{b}}; // error: B::operator X() is not a candidate â *end example*]
|
||
|
||
[5](#over.best.ics.general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2170)
|
||
|
||
For the case where the parameter type is a reference, see [[over.ics.ref]](#over.ics.ref "12.2.4.2.5 Reference binding")[.](#over.best.ics.general-5.sentence-1)
|
||
|
||
[6](#over.best.ics.general-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2173)
|
||
|
||
When the parameter type is not a reference, the implicit conversion
|
||
sequence models a copy-initialization of the parameter from the argument
|
||
expression[.](#over.best.ics.general-6.sentence-1)
|
||
|
||
The implicit conversion sequence is the one required to convert the
|
||
argument expression to a prvalue of the type of
|
||
the parameter[.](#over.best.ics.general-6.sentence-2)
|
||
|
||
[*Note [3](#over.best.ics.general-note-3)*:
|
||
|
||
When the parameter has a class type, this is a conceptual conversion
|
||
defined for the purposes of [[over]](over "12 Overloading"); the actual initialization is
|
||
defined in terms of constructors and is not a conversion[.](#over.best.ics.general-6.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[7](#over.best.ics.general-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2186)
|
||
|
||
When the cv-unqualified version of the type of the argument expression
|
||
is the same as the parameter type,
|
||
the implicit conversion sequence is an identity conversion[.](#over.best.ics.general-7.sentence-1)
|
||
|
||
When the parameter has a class type and the argument expression has a
|
||
(possibly cv-qualified)
|
||
derived class type, the implicit conversion sequence is a
|
||
derived-to-baseconversion from the derived class to the base class[.](#over.best.ics.general-7.sentence-2)
|
||
|
||
A derived-to-base conversion has Conversion rank ([[over.ics.scs]](#over.ics.scs "12.2.4.2.2 Standard conversion sequences"))[.](#over.best.ics.general-7.sentence-3)
|
||
|
||
[*Note [4](#over.best.ics.general-note-4)*:
|
||
|
||
There is no such standard conversion; this derived-to-base conversion exists
|
||
only in the description of implicit conversion sequences[.](#over.best.ics.general-7.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#over.best.ics.general-example-2)*:
|
||
|
||
An implicit conversion sequence from an argument of type const A to a parameter of type A can be formed,
|
||
even if overload resolution for copy-initialization of A from the argument would not find a viable function ([[over.match.ctor]](over.match.ctor "12.2.2.4 Initialization by constructor"), [[over.match.viable]](over.match.viable "12.2.3 Viable functions"))[.](#over.best.ics.general-7.sentence-5)
|
||
|
||
The implicit conversion sequence for that case is the identity sequence; it
|
||
contains no âconversionâ from const A to A[.](#over.best.ics.general-7.sentence-6)
|
||
|
||
â *end example*]
|
||
|
||
[8](#over.best.ics.general-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2210)
|
||
|
||
When the parameter is the implicit object parameter of a static member function,
|
||
the implicit conversion sequence is a standard conversion sequence
|
||
that is neither better nor worse than any other standard conversion sequence[.](#over.best.ics.general-8.sentence-1)
|
||
|
||
[9](#over.best.ics.general-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2215)
|
||
|
||
In all contexts, when converting to the implicit object parameter
|
||
or when converting to the left operand of an assignment operation
|
||
only standard conversion sequences are allowed[.](#over.best.ics.general-9.sentence-1)
|
||
|
||
[*Note [5](#over.best.ics.general-note-5)*:
|
||
|
||
When a conversion to the explicit object parameter occurs,
|
||
it can include user-defined conversion sequences[.](#over.best.ics.general-9.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[10](#over.best.ics.general-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2224)
|
||
|
||
If no conversions are required to match an argument to a
|
||
parameter type, the implicit conversion sequence is the standard
|
||
conversion sequence consisting of the identity conversion ([[over.ics.scs]](#over.ics.scs "12.2.4.2.2 Standard conversion sequences"))[.](#over.best.ics.general-10.sentence-1)
|
||
|
||
[11](#over.best.ics.general-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2229)
|
||
|
||
If no sequence of conversions can be found to convert an argument
|
||
to a parameter type, an implicit conversion sequence cannot be formed[.](#over.best.ics.general-11.sentence-1)
|
||
|
||
[12](#over.best.ics.general-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2233)
|
||
|
||
If there are multiple well-formed implicit conversion sequences
|
||
converting the argument to the parameter type, the implicit
|
||
conversion sequence associated with the parameter is defined to be
|
||
the unique conversion sequence designated the[*ambiguous conversion sequence*](#def:conversion_sequence,ambiguous "12.2.4.2.1 General [over.best.ics.general]")[.](#over.best.ics.general-12.sentence-1)
|
||
|
||
For the purpose of ranking implicit conversion sequences as described
|
||
in [[over.ics.rank]](#over.ics.rank "12.2.4.3 Ranking implicit conversion sequences"), the ambiguous conversion sequence is treated
|
||
as a user-defined conversion sequence that is indistinguishable from any
|
||
other user-defined conversion sequence[.](#over.best.ics.general-12.sentence-2)
|
||
|
||
[*Note [6](#over.best.ics.general-note-6)*:
|
||
|
||
This rule prevents a function from becoming non-viable because of an ambiguous
|
||
conversion sequence for one of its parameters[.](#over.best.ics.general-12.sentence-3)
|
||
|
||
[*Example [3](#over.best.ics.general-example-3)*: class B;class A { A (B&);};class B { operator A (); };class C { C (B&); };void f(A) { }void f(C) { } B b;
|
||
f(b); // error: ambiguous because there is a conversion b â C (via constructor)// and an (ambiguous) conversion b â A (via constructor or conversion function)void f(B) { } f(b); // OK, unambiguous â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
If a function that uses the ambiguous conversion sequence is selected
|
||
as the best viable function, the call will be ill-formed because the conversion
|
||
of one of the arguments in the call is ambiguous[.](#over.best.ics.general-12.sentence-4)
|
||
|
||
[13](#over.best.ics.general-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2266)
|
||
|
||
The three forms of implicit conversion sequences mentioned above
|
||
are defined in the following subclauses[.](#over.best.ics.general-13.sentence-1)
|
||
|
||
#### [12.2.4.2.2](#over.ics.scs) Standard conversion sequences [[over.ics.scs]](over.ics.scs)
|
||
|
||
[1](#over.ics.scs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2272)
|
||
|
||
Table [19](#tab:over.ics.scs "Table 19: Conversions") summarizes the conversions defined in [[conv]](conv "7.3 Standard conversions") and
|
||
partitions them into four disjoint categories: Lvalue Transformation,
|
||
Qualification Adjustment, Promotion, and Conversion[.](#over.ics.scs-1.sentence-1)
|
||
|
||
[*Note [1](#over.ics.scs-note-1)*:
|
||
|
||
These categories are orthogonal with respect to value category,
|
||
cv-qualification, and data representation: the Lvalue Transformations
|
||
do not change the cv-qualification or data
|
||
representation of the type; the Qualification Adjustments do not
|
||
change the value category or data representation of the type; and
|
||
the Promotions and Conversions do not change the
|
||
value category or cv-qualification of the type[.](#over.ics.scs-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#over.ics.scs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2287)
|
||
|
||
[*Note [2](#over.ics.scs-note-2)*:
|
||
|
||
As described in [[conv]](conv "7.3 Standard conversions"),
|
||
a standard conversion sequence either is the Identity conversion
|
||
by itself (that is, no conversion) or consists of one to three
|
||
conversions from the other
|
||
four categories[.](#over.ics.scs-2.sentence-1)
|
||
|
||
If there are two or more conversions in the sequence, the
|
||
conversions are applied in the canonical order:**Lvalue Transformation**,**Promotion** or**Conversion**,**Qualification Adjustment**[.](#over.ics.scs-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[3](#over.ics.scs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2303)
|
||
|
||
Each conversion in Table [19](#tab:over.ics.scs "Table 19: Conversions") also has an associated rank (Exact
|
||
Match, Promotion, or Conversion)[.](#over.ics.scs-3.sentence-1)
|
||
|
||
These are used
|
||
to [rank standard conversion sequences](#over.ics.rank "12.2.4.3 Ranking implicit conversion sequences [over.ics.rank]")[.](#over.ics.scs-3.sentence-2)
|
||
|
||
The rank of a conversion sequence is determined by considering the
|
||
rank of each conversion in the sequence and the rank of any [reference
|
||
binding](#over.ics.ref "12.2.4.2.5 Reference binding [over.ics.ref]")[.](#over.ics.scs-3.sentence-3)
|
||
|
||
If any of those has Conversion rank, the
|
||
sequence has Conversion rank; otherwise, if any of those has Promotion rank,
|
||
the sequence has Promotion rank; otherwise, the sequence has Exact
|
||
Match rank[.](#over.ics.scs-3.sentence-4)
|
||
|
||
Table [19](#tab:over.ics.scs) — Conversions [[tab:over.ics.scs]](./tab:over.ics.scs)
|
||
|
||
| [ð](#tab:over.ics.scs-row-1)<br>**Conversion** | **Category** | **Rank** | **Subclause** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:over.ics.scs-row-2)<br>No conversions required | Identity | | |
|
||
| [ð](#tab:over.ics.scs-row-3)<br> Lvalue-to-rvalue conversion | | | [[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion") |
|
||
| [ð](#tab:over.ics.scs-row-4)<br> Array-to-pointer conversion | Lvalue Transformation | | [[conv.array]](conv.array "7.3.3 Array-to-pointer conversion") |
|
||
| [ð](#tab:over.ics.scs-row-5)<br> Function-to-pointer conversion | | Exact Match | [[conv.func]](conv.func "7.3.4 Function-to-pointer conversion") |
|
||
| [ð](#tab:over.ics.scs-row-6)<br> Qualification conversions | | | [[conv.qual]](conv.qual "7.3.6 Qualification conversions") |
|
||
| [ð](#tab:over.ics.scs-row-7)<br> Function pointer conversion | Qualification Adjustment | | [[conv.fctptr]](conv.fctptr "7.3.14 Function pointer conversions") |
|
||
| [ð](#tab:over.ics.scs-row-8)<br>Integral promotions | | | [[conv.prom]](conv.prom "7.3.7 Integral promotions") |
|
||
| [ð](#tab:over.ics.scs-row-9)<br> Floating-point promotion | Promotion | Promotion | [[conv.fpprom]](conv.fpprom "7.3.8 Floating-point promotion") |
|
||
| [ð](#tab:over.ics.scs-row-10)<br>Integral conversions | | | [[conv.integral]](conv.integral "7.3.9 Integral conversions") |
|
||
| [ð](#tab:over.ics.scs-row-11)<br> Floating-point conversions | | | [[conv.double]](conv.double "7.3.10 Floating-point conversions") |
|
||
| [ð](#tab:over.ics.scs-row-12)<br> Floating-integral conversions | | | [[conv.fpint]](conv.fpint "7.3.11 Floating-integral conversions") |
|
||
| [ð](#tab:over.ics.scs-row-13)<br> Pointer conversions | Conversion | Conversion | [[conv.ptr]](conv.ptr "7.3.12 Pointer conversions") |
|
||
| [ð](#tab:over.ics.scs-row-14)<br> Pointer-to-member conversions | | | [[conv.mem]](conv.mem "7.3.13 Pointer-to-member conversions") |
|
||
| [ð](#tab:over.ics.scs-row-15)<br> Boolean conversions | | | [[conv.bool]](conv.bool "7.3.15 Boolean conversions") |
|
||
|
||
#### [12.2.4.2.3](#over.ics.user) User-defined conversion sequences [[over.ics.user]](over.ics.user)
|
||
|
||
[1](#over.ics.user-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2339)
|
||
|
||
A [*user-defined conversion sequence*](#def:conversion_sequence,user-defined "12.2.4.2.3 User-defined conversion sequences [over.ics.user]") consists of an initial
|
||
standard conversion sequence followed by a user-defined
|
||
conversion ([[class.conv]](class.conv "11.4.8 Conversions")) followed by a second standard
|
||
conversion sequence[.](#over.ics.user-1.sentence-1)
|
||
|
||
If the user-defined conversion is specified
|
||
by a constructor ([[class.conv.ctor]](class.conv.ctor "11.4.8.2 Conversion by constructor")), the initial standard
|
||
conversion sequence converts the source type to the type of the
|
||
first parameter of that constructor[.](#over.ics.user-1.sentence-2)
|
||
|
||
If the user-defined
|
||
conversion is specified by a [conversion function](class.conv.fct "11.4.8.3 Conversion functions [class.conv.fct]"), the
|
||
initial standard conversion sequence
|
||
converts the source type to the type of the
|
||
object parameter of that conversion function[.](#over.ics.user-1.sentence-3)
|
||
|
||
[2](#over.ics.user-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2354)
|
||
|
||
The second standard conversion sequence converts the result of
|
||
the user-defined conversion to the target type for the sequence;
|
||
any reference binding is included in the second standard
|
||
conversion sequence[.](#over.ics.user-2.sentence-1)
|
||
|
||
Since an implicit conversion sequence is an initialization, the
|
||
special rules for initialization by user-defined conversion apply
|
||
when selecting the best user-defined conversion for a
|
||
user-defined conversion sequence (see [over.match.best] and [[over.best.ics]](#over.best.ics "12.2.4.2 Implicit conversion sequences"))[.](#over.ics.user-2.sentence-2)
|
||
|
||
[3](#over.ics.user-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2364)
|
||
|
||
If the user-defined conversion is specified by a
|
||
specialization of a conversion function template,
|
||
the second standard conversion sequence shall have Exact Match rank[.](#over.ics.user-3.sentence-1)
|
||
|
||
[4](#over.ics.user-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2369)
|
||
|
||
A conversion of an expression of class type
|
||
to the same class type is given Exact Match rank, and
|
||
a conversion of an expression of class type
|
||
to a base class of that type is given Conversion rank,
|
||
in spite of the
|
||
fact that a constructor (i.e., a user-defined conversion
|
||
function) is called for those cases[.](#over.ics.user-4.sentence-1)
|
||
|
||
#### [12.2.4.2.4](#over.ics.ellipsis) Ellipsis conversion sequences [[over.ics.ellipsis]](over.ics.ellipsis)
|
||
|
||
[1](#over.ics.ellipsis-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2380)
|
||
|
||
An ellipsis conversion sequence occurs when an argument in a
|
||
function call is matched with the ellipsis parameter
|
||
specification of the function called (see [[expr.call]](expr.call "7.6.1.3 Function call"))[.](#over.ics.ellipsis-1.sentence-1)
|
||
|
||
#### [12.2.4.2.5](#over.ics.ref) Reference binding [[over.ics.ref]](over.ics.ref)
|
||
|
||
[1](#over.ics.ref-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2388)
|
||
|
||
When a parameter of type âreference to cv Tâ
|
||
binds directly ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")) to an argument expression:
|
||
|
||
- [(1.1)](#over.ics.ref-1.1)
|
||
|
||
If the argument expression has a type that
|
||
is a derived class of the parameter type,
|
||
the implicit conversion sequence is a derived-to-base
|
||
conversion ([[over.best.ics]](#over.best.ics "12.2.4.2 Implicit conversion sequences"))[.](#over.ics.ref-1.1.sentence-1)
|
||
|
||
- [(1.2)](#over.ics.ref-1.2)
|
||
|
||
Otherwise,
|
||
if the type of the argument is possibly cv-qualified T, or
|
||
if T is an array type of unknown bound with element type U and
|
||
the argument has an array type of known bound whose
|
||
element type is possibly cv-qualified U,
|
||
the implicit conversion sequence is the identity conversion[.](#over.ics.ref-1.2.sentence-1)
|
||
|
||
- [(1.3)](#over.ics.ref-1.3)
|
||
|
||
Otherwise,
|
||
if T is a function type,
|
||
the implicit conversion sequence is a function pointer conversion[.](#over.ics.ref-1.3.sentence-1)
|
||
|
||
- [(1.4)](#over.ics.ref-1.4)
|
||
|
||
Otherwise, the implicit conversion sequence is a qualification conversion[.](#over.ics.ref-1.4.sentence-1)
|
||
|
||
[*Example [1](#over.ics.ref-example-1)*: struct A {};struct B : public A {} b;int f(A&);int f(B&);int i = f(b); // calls f(B&), an exact match, rather than f(A&), a conversionvoid g() noexcept;int h(void (&)() noexcept); // #1int h(void (&)()); // #2int j = h(g); // calls #1, an exact match, rather than #2, a function pointer conversion â *end example*]
|
||
|
||
If the parameter binds directly to the result of
|
||
applying a conversion function to the argument expression, the implicit
|
||
conversion sequence is a user-defined conversion sequence ([[over.ics.user]](#over.ics.user "12.2.4.2.3 User-defined conversion sequences"))
|
||
whose second standard conversion sequence is
|
||
determined by the above rules[.](#over.ics.ref-1.sentence-2)
|
||
|
||
[2](#over.ics.ref-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2435)
|
||
|
||
When a parameter of reference type is not bound directly to an argument
|
||
expression, the conversion sequence is the one required to convert the argument
|
||
expression to the referenced type according to [[over.best.ics]](#over.best.ics "12.2.4.2 Implicit conversion sequences")[.](#over.ics.ref-2.sentence-1)
|
||
|
||
Conceptually, this conversion sequence corresponds to copy-initializing a
|
||
temporary of the referenced type with the argument expression[.](#over.ics.ref-2.sentence-2)
|
||
|
||
Any difference
|
||
in top-level cv-qualification is subsumed by the initialization itself and
|
||
does not constitute a conversion[.](#over.ics.ref-2.sentence-3)
|
||
|
||
[3](#over.ics.ref-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2445)
|
||
|
||
Except for an implicit object parameter, for which see [[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists"),
|
||
an implicit conversion sequence cannot be formed if it requires
|
||
binding an lvalue reference
|
||
other than a reference to a non-volatile const type
|
||
to an rvalue
|
||
or binding an rvalue reference to an lvalue of object type[.](#over.ics.ref-3.sentence-1)
|
||
|
||
[*Note [1](#over.ics.ref-note-1)*:
|
||
|
||
This means, for example, that a candidate function cannot be a viable
|
||
function if it has a non-const lvalue reference parameter (other than
|
||
the implicit object parameter) and the corresponding argument
|
||
would require a temporary to be created to initialize the lvalue
|
||
reference (see [[dcl.init.ref]](dcl.init.ref "9.5.4 References"))[.](#over.ics.ref-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#over.ics.ref-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2460)
|
||
|
||
Other restrictions on binding a reference to a particular argument
|
||
that are not based on the types of the reference and the argument
|
||
do not affect the formation of an implicit conversion
|
||
sequence, however[.](#over.ics.ref-4.sentence-1)
|
||
|
||
[*Example [2](#over.ics.ref-example-2)*:
|
||
|
||
A function with an âlvalue reference to intâ parameter can
|
||
be a viable candidate even if the corresponding argument is anint bit-field[.](#over.ics.ref-4.sentence-2)
|
||
|
||
The formation of implicit conversion sequences
|
||
treats theint bit-field as anint lvalue and finds an exact
|
||
match with the parameter[.](#over.ics.ref-4.sentence-3)
|
||
|
||
If the function is selected by overload
|
||
resolution, the call will nonetheless be ill-formed because of
|
||
the prohibition on binding a non-const lvalue reference to a bit-field ([[dcl.init.ref]](dcl.init.ref "9.5.4 References"))[.](#over.ics.ref-4.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
#### [12.2.4.2.6](#over.ics.list) List-initialization sequence [[over.ics.list]](over.ics.list)
|
||
|
||
[1](#over.ics.list-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2484)
|
||
|
||
When an argument is an initializer list ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization")), it is not an expression and special rules apply for converting it to a parameter type[.](#over.ics.list-1.sentence-1)
|
||
|
||
[2](#over.ics.list-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2488)
|
||
|
||
If the initializer list is a [*designated-initializer-list*](dcl.init.general#nt:designated-initializer-list "9.5.1 General [dcl.init.general]") and the parameter is not a reference,
|
||
a conversion is only possible if
|
||
the parameter has an aggregate type
|
||
that can be initialized from the initializer list
|
||
according to the rules for aggregate initialization ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")),
|
||
in which case the implicit conversion sequence is
|
||
a user-defined conversion sequence
|
||
whose second standard conversion sequence
|
||
is an identity conversion[.](#over.ics.list-2.sentence-1)
|
||
|
||
[*Note [1](#over.ics.list-note-1)*:
|
||
|
||
Aggregate initialization does not require that
|
||
the members are declared in designation order[.](#over.ics.list-2.sentence-2)
|
||
|
||
If, after overload resolution, the order does not match
|
||
for the selected overload,
|
||
the initialization of the parameter will be ill-formed ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization"))[.](#over.ics.list-2.sentence-3)
|
||
|
||
[*Example [1](#over.ics.list-example-1)*: struct A { int x, y; };struct B { int y, x; };void f(A a, int); // #1void f(B b, ...); // #2void g(A a); // #3void g(B b); // #4void h() { f({.x = 1, .y = 2}, 0); // OK; calls #1 f({.y = 2, .x = 1}, 0); // error: selects #1, initialization of a fails// due to non-matching member order ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization")) g({.x = 1, .y = 2}); // error: ambiguous between #3 and #4} â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[3](#over.ics.list-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2523)
|
||
|
||
Otherwise,
|
||
if the parameter type is an aggregate class X and the initializer list has a
|
||
single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence is the one
|
||
required to convert the element to the parameter type[.](#over.ics.list-3.sentence-1)
|
||
|
||
[4](#over.ics.list-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2530)
|
||
|
||
Otherwise, if the parameter type is a character array[106](#footnote-106 "Since there are no parameters of array type, this will only occur as the referenced type of a reference parameter.") and the initializer list has a single element that is an appropriately-typed[*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]") ([[dcl.init.string]](dcl.init.string "9.5.3 Character arrays")), the implicit conversion
|
||
sequence is the identity conversion[.](#over.ics.list-4.sentence-1)
|
||
|
||
[5](#over.ics.list-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2540)
|
||
|
||
Otherwise, if the parameter type is std::initializer_list<X> and all the elements
|
||
of the initializer list can be implicitly converted to X, the implicit
|
||
conversion sequence is the worst conversion necessary to convert an element of
|
||
the list to X, or if the initializer list has no elements, the identity
|
||
conversion[.](#over.ics.list-5.sentence-1)
|
||
|
||
This conversion can be a user-defined conversion even in
|
||
the context of a call to an initializer-list constructor[.](#over.ics.list-5.sentence-2)
|
||
|
||
[*Example [2](#over.ics.list-example-2)*: void f(std::initializer_list<int>);
|
||
f( {} ); // OK, f(initializer_list<int>) identity conversion f( {1,2,3} ); // OK, f(initializer_list<int>) identity conversion f( {'a','b'} ); // OK, f(initializer_list<int>) integral promotion f( {1.0} ); // error: narrowingstruct A { A(std::initializer_list<double>); // #1 A(std::initializer_list<std::complex<double>>); // #2 A(std::initializer_list<std::string>); // #3};
|
||
A a{ 1.0,2.0 }; // OK, uses #1void g(A);
|
||
g({ "foo", "bar" }); // OK, uses #3typedef int IA[3];void h(const IA&);
|
||
h({ 1, 2, 3 }); // OK, identity conversion â *end example*]
|
||
|
||
[6](#over.ics.list-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2572)
|
||
|
||
Otherwise, if the parameter type is âarray of N Xâ
|
||
or âarray of unknown bound of Xâ,
|
||
if there exists an implicit conversion sequence
|
||
from each element of the initializer list
|
||
(and from {} in the former case
|
||
if N exceeds the number of elements in the initializer list)
|
||
to X, the implicit conversion sequence is
|
||
the worst such implicit conversion sequence[.](#over.ics.list-6.sentence-1)
|
||
|
||
[7](#over.ics.list-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2582)
|
||
|
||
Otherwise, if the parameter is a non-aggregate class X and overload
|
||
resolution per [[over.match.list]](over.match.list "12.2.2.8 Initialization by list-initialization") chooses a single best constructor C ofX to perform the initialization of an object of type X from the
|
||
argument initializer list:
|
||
|
||
- [(7.1)](#over.ics.list-7.1)
|
||
|
||
If C is not an initializer-list constructor
|
||
and the initializer list has a single element of type cv U,
|
||
where U is X or a class derived from X,
|
||
the implicit conversion sequence has Exact Match rank if U is X,
|
||
or Conversion rank if U is derived from X[.](#over.ics.list-7.1.sentence-1)
|
||
|
||
- [(7.2)](#over.ics.list-7.2)
|
||
|
||
Otherwise, the implicit conversion sequence is a user-defined
|
||
conversion sequence whose second standard conversion sequence is an
|
||
identity conversion[.](#over.ics.list-7.2.sentence-1)
|
||
|
||
If multiple constructors are viable but none is better than
|
||
the others, the implicit conversion sequence is the ambiguous conversion
|
||
sequence[.](#over.ics.list-7.sentence-2)
|
||
|
||
User-defined conversions are allowed for conversion of the initializer
|
||
list elements to the constructor parameter types except as noted
|
||
in [[over.best.ics]](#over.best.ics "12.2.4.2 Implicit conversion sequences")[.](#over.ics.list-7.sentence-3)
|
||
|
||
[*Example [3](#over.ics.list-example-3)*: struct A { A(std::initializer_list<int>);};void f(A);
|
||
f( {'a', 'b'} ); // OK, f(A(std::initializer_list<int>)) user-defined conversionstruct B { B(int, double);};void g(B);
|
||
g( {'a', 'b'} ); // OK, g(B(int, double)) user-defined conversion g( {1.0, 1.0} ); // error: narrowingvoid f(B);
|
||
f( {'a', 'b'} ); // error: ambiguous f(A) or f(B)struct C { C(std::string);};void h(C);
|
||
h({"foo"}); // OK, h(C(std::string("foo")))struct D { D(A, C);};void i(D);
|
||
i({ {1,2}, {"bar"} }); // OK, i(D(A(std::initializer_list<int>{1,2}), C(std::string("bar")))) â *end example*]
|
||
|
||
[8](#over.ics.list-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2636)
|
||
|
||
Otherwise, if the parameter has an aggregate type which can be initialized from
|
||
the initializer list according to the rules for aggregate
|
||
initialization ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")), the implicit conversion sequence is a
|
||
user-defined conversion sequence whose second standard conversion
|
||
sequence is an identity conversion[.](#over.ics.list-8.sentence-1)
|
||
|
||
[*Example [4](#over.ics.list-example-4)*: struct A {int m1; double m2;};
|
||
|
||
void f(A);
|
||
f( {'a', 'b'} ); // OK, f(A(int,double)) user-defined conversion f( {1.0} ); // error: narrowing â *end example*]
|
||
|
||
[9](#over.ics.list-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2655)
|
||
|
||
Otherwise, if the parameter is a reference, see [[over.ics.ref]](#over.ics.ref "12.2.4.2.5 Reference binding")[.](#over.ics.list-9.sentence-1)
|
||
|
||
[*Note [2](#over.ics.list-note-2)*:
|
||
|
||
The rules in this subclause will apply for initializing the underlying temporary
|
||
for the reference[.](#over.ics.list-9.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [5](#over.ics.list-example-5)*: struct A {int m1; double m2;};
|
||
|
||
void f(const A&);
|
||
f( {'a', 'b'} ); // OK, f(A(int,double)) user-defined conversion f( {1.0} ); // error: narrowingvoid g(const double &);
|
||
g({1}); // same conversion as int to double â *end example*]
|
||
|
||
[10](#over.ics.list-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2677)
|
||
|
||
Otherwise, if the parameter type is not a class:
|
||
|
||
- [(10.1)](#over.ics.list-10.1)
|
||
|
||
if the initializer list has one element that is not itself an initializer list,
|
||
the implicit conversion sequence is the one required to convert the element to
|
||
the parameter type;
|
||
[*Example [6](#over.ics.list-example-6)*: void f(int);
|
||
f( {'a'} ); // OK, same conversion as char to int f( {1.0} ); // error: narrowing â *end example*]
|
||
|
||
- [(10.2)](#over.ics.list-10.2)
|
||
|
||
if the initializer list has no elements, the implicit conversion sequence
|
||
is the identity conversion[.](#over.ics.list-10.sentence-1)
|
||
[*Example [7](#over.ics.list-example-7)*: void f(int);
|
||
f( { } ); // OK, identity conversion â *end example*]
|
||
|
||
[11](#over.ics.list-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2701)
|
||
|
||
In all cases other than those enumerated above, no conversion is possible[.](#over.ics.list-11.sentence-1)
|
||
|
||
[106)](#footnote-106)[106)](#footnoteref-106)
|
||
|
||
Since there are no parameters of array type,
|
||
this will only occur as the referenced type of a reference parameter[.](#footnote-106.sentence-1)
|
||
|
||
#### [12.2.4.3](#over.ics.rank) Ranking implicit conversion sequences [[over.ics.rank]](over.ics.rank)
|
||
|
||
[1](#over.ics.rank-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]")[.](#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[.](#over.ics.rank-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]")[.](#over.ics.rank-1.sentence-3)
|
||
|
||
[2](#over.ics.rank-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)](#over.ics.rank-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)](#over.ics.rank-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]")[.](#over.ics.rank-2.sentence-1)
|
||
|
||
[3](#over.ics.rank-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)](#over.ics.rank-3.1)
|
||
|
||
List-initialization sequence L1 is a better conversion sequence than
|
||
list-initialization sequence L2 if
|
||
* [(3.1.1)](#over.ics.rank-3.1.1)
|
||
|
||
L1 converts to std::initializer_list<X> for some X andL2 does not, or, if not that,
|
||
|
||
* [(3.1.2)](#over.ics.rank-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[.](#over.ics.rank-3.1.sentence-1)
|
||
[*Example [1](#over.ics.rank-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](#over.ics.rank-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)](#over.ics.rank-3.2)
|
||
|
||
Standard conversion sequenceS1 is a better conversion
|
||
sequence than standard conversion sequenceS2 if
|
||
* [(3.2.1)](#over.ics.rank-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)](#over.ics.rank-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)](#over.ics.rank-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](#over.ics.rank-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)](#over.ics.rank-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](#over.ics.rank-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)](#over.ics.rank-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](#over.ics.rank-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)](#over.ics.rank-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](#over.ics.rank-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)](#over.ics.rank-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*[.](#over.ics.rank-3.2.sentence-1)
|
||
[*Example [7](#over.ics.rank-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)](#over.ics.rank-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[.](#over.ics.rank-3.3.sentence-1)
|
||
[*Example [8](#over.ics.rank-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](#over.ics.rank-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[.](#over.ics.rank-4.sentence-1)
|
||
|
||
Two conversion sequences with the same rank are indistinguishable unless
|
||
one of the following rules applies:
|
||
|
||
- [(4.1)](#over.ics.rank-4.1)
|
||
|
||
A conversion that does not convert a pointer or a pointer to member
|
||
tobool is better than one that does[.](#over.ics.rank-4.1.sentence-1)
|
||
|
||
- [(4.2)](#over.ics.rank-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[.](#over.ics.rank-4.2.sentence-1)
|
||
|
||
- [(4.3)](#over.ics.rank-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)](#over.ics.rank-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)](#over.ics.rank-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[.](#over.ics.rank-4.3.sentence-1)
|
||
[*Example [9](#over.ics.rank-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)](#over.ics.rank-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*[.](#over.ics.rank-4.4.sentence-1)
|
||
|
||
- [(4.5)](#over.ics.rank-4.5)
|
||
|
||
If classB is derived directly or indirectly from classA and classC is derived directly or indirectly fromB,
|
||
* [(4.5.1)](#over.ics.rank-4.5.1)
|
||
|
||
conversion ofC* toB* is better than conversion ofC* toA*,
|
||
[*Example [10](#over.ics.rank-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)](#over.ics.rank-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)](#over.ics.rank-4.5.3)
|
||
|
||
conversion ofA::* toB::* is better than conversion ofA::* toC::*,
|
||
|
||
* [(4.5.4)](#over.ics.rank-4.5.4)
|
||
|
||
conversion ofC toB is better than conversion ofC toA,
|
||
|
||
* [(4.5.5)](#over.ics.rank-4.5.5)
|
||
|
||
conversion ofB* toA* is better than conversion ofC* toA*,
|
||
|
||
* [(4.5.6)](#over.ics.rank-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)](#over.ics.rank-4.5.7)
|
||
|
||
conversion ofB::* toC::* is better than conversion
|
||
ofA::* toC::*,
|
||
and
|
||
|
||
* [(4.5.8)](#over.ics.rank-4.5.8)
|
||
|
||
conversion ofB toA is better than conversion ofC toA[.](#over.ics.rank-4.5.sentence-1)
|
||
|
||
[*Note [1](#over.ics.rank-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]); in
|
||
all other contexts, the source types will be the same and the target
|
||
types will be different[.](#over.ics.rank-4.5.sentence-2)
|
||
â *end note*]
|