Created on 2020-10-01.00:00:00 last changed 2 weeks ago
[ 2025-10-21; Priority set to 4 based on age of issue and lack of activity. ]
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 [meta.unary.prop] p8, or do we want to give a more useful/meaningful answer here?
Should we revisit [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.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2025-10-21 15:20:04 | admin | set | messages: + msg15332 |
| 2020-10-01 00:00:00 | admin | create | |