 # Re: List initialization

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 10 Jun 2021 12:39:35 +0100
On Thu, 10 Jun 2021 at 12:18, Vladimir Grigoriev via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> In the paragraph # 3 of the section 12.4.3.2 Ranking implicit conversion
> sequences of the C++ 20 Standard there is written
>
> (3.1) — List-initialization sequence L1 is a better conversion sequence
> than list-initialization sequence L2 if
>
> and
>
> (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, or n1 = n2 and L2 converts to an array of
> unknown bound and L1 does not,
>
> This description is entirely unclear. For starters what is «the number of
> initialized elements»? Is it the size of the initialized array or is it the
> number of initializers in the initializer ;list?
>

It is the size of the initialized array, which is the extent of the array
if the array is an array of known bound, and the number of initializers in
the initializer list if the array is an array of unknown bound.

> Secondly, how can be n1 == n2 if the initialized arrays of unknown
> bounds?
>

If both arrays are arrays of unknown bound, then both n1 and n2 will be the
number of initializers in the initializer list, and thus n1 == n2 will hold.

If one array is an array of unknown bound and the other is an array of
known bound, then, supposing WLOG L1 converts to an array of size m1 and L2
converts to an array of unknown bound, n1 will equal m1 and n2 will equal
the number of initializers in the initializer list, so n1 == n2 will hold
precisely when the number of initializers in the initializer list is m1.

Thirdly, from the first statement (3.1) it follows that L1 is better than
> L2 when «L2 converts to an array of unknown bound and L1 does not» However
> in this example in the C++ Standard
>
> void f(int (&&)[] ); // #1
> void f(double (&&)[] ); // #2
> void f(int (&&)); // #3
> f( {1} ); // Calls #1: Better than #2 due to conversion, better than #3
> due to bounds
>
> the function #1 is selected instead of the function #3. Is it a typo?
>

In that example, denoting n1 n2 n3 as the number of elements initialized in
the conversion for #1 #2 #3 respectively, n1 == 1 whereas n3 == 2. So the
first conjunct of the second disjunct of the second conjunct of
[over.ics.rank]/3.1.2 does not hold and #3 is not better than #1.

There is implementation variance; Clang erroneously selects #3.

> With best regards,