This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of LEWG status.

### 3486. `is_constructible<T[], T...>` may be misleading in C++20

Section: 20.15.5.4 [meta.unary.prop] Status: LEWG Submitter: Jonathan Wakely Opened: 2020-10-01 Last modified: 2020-10-01

Priority: Not Prioritized

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with LEWG status.

Discussion:

According to the current wording, `std::is_constructible<int[], int>` should be true, because the preconditions are met (all types are complete types or unbounded arrays) and the variable definition is well-formed since C++20:

>     using T = int[];
>     T t(declval<int>()); // equiv. to int t[] = {1};

However, this doesn't construct an object of type `int[]` because it deduces the array bound from the initializers, and so constructs `int[1]`, which is not the type being asked about. It seems more logical for the trait to give a false result for an unbounded array, because it's an incomplete type, and no `int[]` can ever be constructed.

On the reflector Tim Song noted:

> On the other hand, the result is something to which an `int(&)[]` can be bound directly thanks to another C++20 change, so a lot of things might Just Work (for some definition of "Work") despite the type difference.

This seems to me a reasonable rationale for `is_constructible<int(&&)[], int>` to be true (which it is today), but not for `int[]`.

Peter Dimov replied:

> Placement new, which is often the way to construct we're interested in, is not going to work even for `T[2]`.

For example:

>     using T2 = int[2];
>     T2 x;
>     new(x) T2(1, 2); // ill-formed

We need to decide what behaviour we want here. Do we just want `is_constructible` to reflect the `T(declval<Args...>);` construct as currently specified in 20.15.5.4 [meta.unary.prop] p8, or do we want to give a more useful/meaningful answer here?

Should we revisit 20.15.5.4 [meta.unary.prop] p8 in the light of parenthesized aggregate init, so that `is_constructible<T[], T>` and `is_constructible<T[1], T>` are false?

There may be some interaction with LWG 3436.

Proposed resolution: