196 lines
9.2 KiB
Markdown
196 lines
9.2 KiB
Markdown
[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)
|