Стандарт C++ 11 (1119564), страница 86
Текст из файла (страница 86)
— end note ]4Other restrictions on binding a reference to a particular argument that are not based on the types ofthe reference and the argument do not affect the formation of a standard conversion sequence, however.[ Example: a function with an “lvalue reference to int” parameter can be a viable candidate even if thecorresponding argument is an int bit-field.
The formation of implicit conversion sequences treats the intbit-field as an int lvalue and finds an exact match with the parameter. If the function is selected by overloadresolution, the call will nonetheless be ill-formed because of the prohibition on binding a non-const lvaluereference to a bit-field (8.5.3).
— end example ]5The binding of a reference to an expression that is reference-compatible with added qualification influencesthe rank of a standard conversion; see 13.3.3.2 and 8.5.3.13.3.3.1.5List-initialization sequence[over.ics.list]1When an argument is an initializer list (8.5.4), it is not an expression and special rules apply for convertingit to a parameter type.2If the parameter type is std::initializer_list<X> or “array of X”135 and all the elements of the initializerlist can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary toconvert an element of the list to X. This conversion can be a user-defined conversion even in the context ofa call to an initializer-list constructor.
[ Example:void f(std::initializer_list<int>);f( {1,2,3} );// OK: f(initializer_list<int>) identity conversionf( {’a’,’b’} );// OK: f(initializer_list<int>) integral promotionf( {1.0} );// error: narrowingstruct A {A(std::initializer_list<double>);A(std::initializer_list<complex<double>>);A(std::initializer_list<std::string>);};A a{ 1.0,2.0 };// OK, uses #1void g(A);g({ "foo", "bar" });// #1// #2// #3// OK, uses #3typedef int IA[3];void h(const IA&);135) Since there are no parameters of array type, this will only occur as the underlying type of a reference parameter.§ 13.3.3.1.5306© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)h({ 1, 2, 3 });// OK: identity conversion— end example ]3Otherwise, if the parameter is a non-aggregate class X and overload resolution per 13.3.1.7 chooses a singlebest constructor of X to perform the initialization of an object of type X from the argument initializer list, theimplicit conversion sequence is a user-defined conversion sequence.
If multiple constructors are viable butnone is better than the others, the implicit conversion sequence is the ambiguous conversion sequence. Userdefined conversions are allowed for conversion of the initializer list elements to the constructor parametertypes except as noted in 13.3.3.1. [ Example: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’} );g( {1.0, 1,0} );// OK: g(B(int,double)) user-defined conversion// 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 {C(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 ]4Otherwise, if the parameter has an aggregate type which can be initialized from the initializer list accordingto the rules for aggregate initialization (8.5.1), the implicit conversion sequence is a user-defined conversionsequence.
[ Example:struct A {int m1;double m2;};void f(A);f( {’a’, ’b’} );f( {1.0} );// OK: f(A(int,double)) user-defined conversion// error: narrowing— end example ]§ 13.3.3.1.5© ISO/IEC 2011 – All rights reserved307ISO/IEC 14882:2011(E)5Otherwise, if the parameter is a reference, see 13.3.3.1.4. [ Note: The rules in this section will apply forinitializing the underlying temporary for the reference.
— end note ] [ Example:struct A {int m1;double m2;};void f(const A&);f( {’a’, ’b’} );f( {1.0} );// OK: f(A(int,double)) user-defined conversion// error: narrowingvoid g(const double &);g({1});// same conversion as int to double— end example ]6Otherwise, if the parameter type is not a class:— if the initializer list has one element, the implicit conversion sequence is the one required to convertthe element to the parameter type; [ Example:void f(int);f( {’a’} );f( {1.0} );// OK: same conversion as char to int// error: narrowing— end example ]— if the initializer list has no elements, the implicit conversion sequence is the identity conversion.[ Example:void f(int);f( { } );// OK: identity conversion— end example ]7In all cases other than those enumerated above, no conversion is possible.13.3.3.2Ranking implicit conversion sequences[over.ics.rank]113.3.3.2 defines a partial ordering of implicit conversion sequences based on the relationships better conversionsequence and better conversion.
If an implicit conversion sequence S1 is defined by these rules to be a betterconversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1. Ifconversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said tobe indistinguishable conversion sequences.2When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)— a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and— a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion sequence (13.3.3.1.3).3Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one ofthe following rules applies:§ 13.3.3.2308© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— Standard conversion sequence S1 is a better conversion sequence than standard conversion sequenceS2 if— S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical formdefined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence isconsidered to be a subsequence of any non-identity conversion sequence) or, if not that,— the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below, or, if not that,— S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (4.4),respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualificationsignature of type T2.
[ Example:intintintintf(const int *);f(int *);i;j = f(&i);// calls f(int*)— end example ] or, if not that,— S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of anon-static member function declared without a ref-qualifier, and S1 binds an rvalue reference toan rvalue and S2 binds an lvalue reference.[ Example:int i;int f1();int&& f2();int g(const int&);int g(const int&&);int j = g(i);int k = g(f1());int l = g(f2());struct A {A& operator<<(int);void p() &;void p() &&;};A& operator<<(A&&, char);A() << 1;A() << ’c’;A a;a << 1;a << ’c’;A().p();a.p();// calls g(const int&)// calls g(const int&&)// calls g(const int&&)// calls A::operator<<(int)// calls operator<<(A&&, char)////////callscallscallscallsA::operator<<(int)A::operator<<(int)A::p()&&A::p()&— end example ] or, if not that,— S1 and S2 are reference bindings (8.5.3) and S1 binds an lvalue reference to a function lvalue andS2 binds an rvalue reference to a function lvalue.
[ Example:template<class T> int f(T&);template<class T> int f(T&&);void g();§ 13.3.3.2© ISO/IEC 2011 – All rights reserved309ISO/IEC 14882:2011(E)int i1 = f(g);// calls f(T&)— end example ]— S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the sametype except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refersis more cv-qualified than the type to which the reference initialized by S1 refers.
[ Example:intintintintf(const int &);f(int &);g(const int &);g(int);int i;int j = f(i);int k = g(i);struct X {void f() const;void f();};void g(const X& a, X b) {a.f();b.f();}// calls f(int &)// ambiguous// calls X::f() const// calls X::f()— end example ]— User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or aggregateinitialization and the second standard conversion sequence of U1 is better than the second standardconversion sequence of U2. [ Example:struct A {operator short();} a;int f(int);int f(float);int i = f(a);// calls f(int), because short → int is// better than short → float.— end example ]— List-initialization sequence L1 is a better conversion sequence than list-initialization sequence L2 if L1converts to std::initializer_list<X> for some X and L2 does not.4Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than aPromotion, which is a better conversion than a Conversion.
Two conversion sequences with the same rankare indistinguishable unless one of the following rules applies:— A conversion that does not convert a pointer, a pointer to member, or std::nullptr_t to bool isbetter than one that does.— If class B is derived directly or indirectly from class A, conversion of B* to A* is better than conversionof B* to void*, and conversion of A* to void* is better than conversion of B* to void*.— If class B is derived directly or indirectly from class A and class C is derived directly or indirectly fromB,§ 13.3.3.2310© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— conversion of C* to B* is better than conversion of C* to A*, [ Example:struct A {};struct B : public A {};struct C : public B {};C *pc;int f(A *);int f(B *);int i = f(pc);// calls f(B*)— end example ]— binding of an expression of type C to a reference of type B& is better than binding an expressionof type C to a reference of type A&,— conversion of A::* to B::* is better than conversion of A::* to C::*,— conversion of C to B is better than conversion of C to A,— conversion of B* to A* is better than conversion of C* to A*,— binding of an expression of type B to a reference of type A& is better than binding an expressionof type C to a reference of type A&,— conversion of B::* to C::* is better than conversion of A::* to C::*, and— conversion of B to A is better than conversion of C to A.[ Note: Compared conversion sequences will have different source types only in the context of comparingthe second standard conversion sequence of an initialization by user-defined conversion (see 13.3.3);in all other contexts, the source types will be the same and the target types will be different.