C++ Logo


Advanced search

Subject: Re: Might be a vague wording about the worst conversion rule for list-initialization sequence.
From: Brian Bi (bbi5291_at_[hidden])
Date: 2021-01-09 13:55:49

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*

STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups