1

Reproducible example:

#include <type_traits>
static_assert(std::is_constructible_v<int[2], int, int>, "fails against my expectations");

I tested this with clang 5 and gcc 7.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
kamikaze
  • 1,529
  • 8
  • 18
  • 1
    Why do you expect it to be true? An array does not have a constructor. From [this](http://en.cppreference.com/w/cpp/types/is_constructible): "*If `T` is an object or reference type and the variable definition `T obj(std::declval()...);` is well-formed, provides the member constant value equal to `true`. **In all other cases, value is `false`**.*" `int obj[2](int, int)` is not well-defined. Dont confuse construction with aggregate initialization. – Remy Lebeau Nov 28 '17 at 07:50

2 Answers2

8

From the ref:

If T is an object or reference type and the variable definition T obj(std::declval<Args>()...); is well-formed, provides the member constant value equal to true. In all other cases, value is false.

In your example T obj(std::declval<Args>()...); is not well-formed.

This is because int[2] is a plain array, which doesn't have any constructor whatsoever.

As a result, this:

int obj[2](int, int);

is ill-formed.

Arrays are aggregates, thus aggregate initialization comes into play here, not construction.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Do you know if there is a way to check if a type is constructible with aggregates? Ie, is_aggregate_initializable would be true? – BWG Jul 18 '22 at 04:36
2

The purpose and definition of std::is_constructible is to check if an object of the specified type may be constructed as in:

T obj(std::declval<Args>()...);

And the above is simply not well-formed for an array. An array doesn't have any constructors, it is an aggregate and should be initialized with aggregate initialization.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458