C++ Logo

std-discussion

Advanced search

Re: Might be a vague wording about the worst conversion rule for list-initialization sequence.

From: jim x <xmh970252187_at_[hidden]>
Date: Tue, 12 Jan 2021 10:42:03 +0800
Actually, I don't know how to file a CWG issue.

Brian Bi <bbi5291_at_[hidden]> 于2021年1月10日周日 上午3:56写道:

> I agree the wording is unclear. You should file a CWG issue, if there is
> not already one.
>
> On Wed, Dec 30, 2020 at 9:42 PM jim x via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
>> About the implicit conversion sequence for the parameter of type `
>> std::initializer_­list<X>`, the relevant rule is worded by:
>> >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.
>>
>> So, consider this example:
>> ````
>> #include <initializer_list>
>> struct A{
>> operator short(){
>> return 0;
>> }
>> };
>> struct B{
>> operator bool(){
>> return 0;
>> }
>> };
>> void fun(std::initializer_list<int>){}
>> void fun(std::initializer_list<bool>){}
>> int main(){
>> fun({A{},B{}});
>> }
>> ````
>> For the parameter type `std::initializer_list<int>`, regardless of the
>> conversion function of `A` or `B`, they all have the user-defined
>> conversion with the second standard conversion sequence
>> an integral promotion. So, which is the worst conversion?
>>
>> For the parameter type `std::initializer_list<bool>`, from `A` to `bool`,
>> the conversion sequence comprises a user-defined conversion with the second
>> standard conversion an *integral conversion. *Rather, from `B` to
>> `bool`, a user-defined conversion with the second standard conversion a
>> identity conversion. Hence, the worst conversion for
>> `std::initializer_list<bool>` is that of from `A` to `bool`.
>>
>> So, the key point falls at which conversion function is the worst
>> conversion for `std::initializer_list<int>`? If it is `A::operator int`,
>> then the following rule will apply to determine the best overload:
>> >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 they initialize the
>> same class in an aggregate initialization and in either case the second
>> standard conversion sequence of U1 is better than the second standard
>> conversion sequence of U2.
>>
>> Otherwise, if `B::operator bool` is considered as the worst conversion
>> for `std::initializer_list<int>`, then the above rule cannot apply here.
>> That means calling `fun` will be ambiguous.
>>
>> Here <https://godbolt.org/z/EbjTcE>is the result of the example, GCC
>> reports an ambiguous error. Instead, the other compilers chose `void
>> fun(std::initializer_list<int>)` for `fun({A{},B{}})`. It is vague here. I
>> think [over.ics.list#5] <https://eel.is/c++draft/over.ics.list#5> should
>> clarify for this example. The rule should be reworded, to point out which
>> is the worst conversion between these conversions when they are
>> indistinguishable, In order to against the other when performing overload
>> resolution.
>> --
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>
>
> --
> *Brian Bi*
>

Received on 2021-01-11 20:42:20