Init
This commit is contained in:
19
cppdraft/over/ics/ellipsis.md
Normal file
19
cppdraft/over/ics/ellipsis.md
Normal file
@@ -0,0 +1,19 @@
|
||||
[over.ics.ellipsis]
|
||||
|
||||
# 12 Overloading [[over]](./#over)
|
||||
|
||||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.ellipsis)
|
||||
|
||||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.ellipsis)
|
||||
|
||||
#### 12.2.4.2 Implicit conversion sequences [[over.best.ics]](over.best.ics#over.ics.ellipsis)
|
||||
|
||||
#### 12.2.4.2.4 Ellipsis conversion sequences [over.ics.ellipsis]
|
||||
|
||||
[1](#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"))[.](#1.sentence-1)
|
||||
195
cppdraft/over/ics/list.md
Normal file
195
cppdraft/over/ics/list.md
Normal file
@@ -0,0 +1,195 @@
|
||||
[over.ics.list]
|
||||
|
||||
# 12 Overloading [[over]](./#over)
|
||||
|
||||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.list)
|
||||
|
||||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.list)
|
||||
|
||||
#### 12.2.4.2 Implicit conversion sequences [[over.best.ics]](over.best.ics#over.ics.list)
|
||||
|
||||
#### 12.2.4.2.6 List-initialization sequence [over.ics.list]
|
||||
|
||||
[1](#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[.](#1.sentence-1)
|
||||
|
||||
[2](#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[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Aggregate initialization does not require that
|
||||
the members are declared in designation order[.](#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"))[.](#2.sentence-3)
|
||||
|
||||
[*Example [1](#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](#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[.](#3.sentence-1)
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
|
||||
[5](#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[.](#5.sentence-1)
|
||||
|
||||
This conversion can be a user-defined conversion even in
|
||||
the context of a call to an initializer-list constructor[.](#5.sentence-2)
|
||||
|
||||
[*Example [2](#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](#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[.](#6.sentence-1)
|
||||
|
||||
[7](#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)](#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[.](#7.1.sentence-1)
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
Otherwise, the implicit conversion sequence is a user-defined
|
||||
conversion sequence whose second standard conversion sequence is an
|
||||
identity conversion[.](#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[.](#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")[.](#7.sentence-3)
|
||||
|
||||
[*Example [3](#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](#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[.](#8.sentence-1)
|
||||
|
||||
[*Example [4](#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](#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")[.](#9.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The rules in this subclause will apply for initializing the underlying temporary
|
||||
for the reference[.](#9.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [5](#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](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2677)
|
||||
|
||||
Otherwise, if the parameter type is not a class:
|
||||
|
||||
- [(10.1)](#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](#example-6)*: void f(int);
|
||||
f( {'a'} ); // OK, same conversion as char to int f( {1.0} ); // error: narrowing â *end example*]
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
if the initializer list has no elements, the implicit conversion sequence
|
||||
is the identity conversion[.](#10.sentence-1)
|
||||
[*Example [7](#example-7)*: void f(int);
|
||||
f( { } ); // OK, identity conversion â *end example*]
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2701)
|
||||
|
||||
In all cases other than those enumerated above, no conversion is possible[.](#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)
|
||||
245
cppdraft/over/ics/rank.md
Normal file
245
cppdraft/over/ics/rank.md
Normal file
@@ -0,0 +1,245 @@
|
||||
[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*]
|
||||
112
cppdraft/over/ics/ref.md
Normal file
112
cppdraft/over/ics/ref.md
Normal file
@@ -0,0 +1,112 @@
|
||||
[over.ics.ref]
|
||||
|
||||
# 12 Overloading [[over]](./#over)
|
||||
|
||||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.ref)
|
||||
|
||||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.ref)
|
||||
|
||||
#### 12.2.4.2 Implicit conversion sequences [[over.best.ics]](over.best.ics#over.ics.ref)
|
||||
|
||||
#### 12.2.4.2.5 Reference binding [over.ics.ref]
|
||||
|
||||
[1](#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)](#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"))[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#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[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
Otherwise,
|
||||
if T is a function type,
|
||||
the implicit conversion sequence is a function pointer conversion[.](#1.3.sentence-1)
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
Otherwise, the implicit conversion sequence is a qualification conversion[.](#1.4.sentence-1)
|
||||
|
||||
[*Example [1](#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[.](#1.sentence-2)
|
||||
|
||||
[2](#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")[.](#2.sentence-1)
|
||||
|
||||
Conceptually, this conversion sequence corresponds to copy-initializing a
|
||||
temporary of the referenced type with the argument expression[.](#2.sentence-2)
|
||||
|
||||
Any difference
|
||||
in top-level cv-qualification is subsumed by the initialization itself and
|
||||
does not constitute a conversion[.](#2.sentence-3)
|
||||
|
||||
[3](#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[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#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"))[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
|
||||
[*Example [2](#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[.](#4.sentence-2)
|
||||
|
||||
The formation of implicit conversion sequences
|
||||
treats theint bit-field as anint lvalue and finds an exact
|
||||
match with the parameter[.](#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"))[.](#4.sentence-4)
|
||||
|
||||
â *end example*]
|
||||
86
cppdraft/over/ics/scs.md
Normal file
86
cppdraft/over/ics/scs.md
Normal file
@@ -0,0 +1,86 @@
|
||||
[over.ics.scs]
|
||||
|
||||
# 12 Overloading [[over]](./#over)
|
||||
|
||||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.scs)
|
||||
|
||||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.scs)
|
||||
|
||||
#### 12.2.4.2 Implicit conversion sequences [[over.best.ics]](over.best.ics#over.ics.scs)
|
||||
|
||||
#### 12.2.4.2.2 Standard conversion sequences [over.ics.scs]
|
||||
|
||||
[1](#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[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#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[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L2287)
|
||||
|
||||
[*Note [2](#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[.](#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**[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#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)[.](#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]")[.](#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]")[.](#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[.](#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") |
|
||||
65
cppdraft/over/ics/user.md
Normal file
65
cppdraft/over/ics/user.md
Normal file
@@ -0,0 +1,65 @@
|
||||
[over.ics.user]
|
||||
|
||||
# 12 Overloading [[over]](./#over)
|
||||
|
||||
## 12.2 Overload resolution [[over.match]](over.match#over.ics.user)
|
||||
|
||||
### 12.2.4 Best viable function [[over.match.best]](over.match.best#over.ics.user)
|
||||
|
||||
#### 12.2.4.2 Implicit conversion sequences [[over.best.ics]](over.best.ics#over.ics.user)
|
||||
|
||||
#### 12.2.4.2.3 User-defined conversion sequences [over.ics.user]
|
||||
|
||||
[1](#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[.](#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[.](#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[.](#1.sentence-3)
|
||||
|
||||
[2](#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[.](#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]](over.match.best "12.2.4 Best viable function") and [[over.best.ics]](over.best.ics "12.2.4.2 Implicit conversion sequences"))[.](#2.sentence-2)
|
||||
|
||||
[3](#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[.](#3.sentence-1)
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
Reference in New Issue
Block a user