Edit: In a comment below, Daniel points out he was really asking about why a std::array
of one single type could not be initialized by a list containing entries of different types (for example two int
and a double
). Not why a std::array
has to be one single type.
It doesn't address Daniel's request for a rationale but some C++ environments support the experimental\array header and the std::experimental::make_array
class which does allow initialisation of a std::array from different types. The array type can be deduced or specified...
#include <array>
#include <experimental/array>
// creates array of doubles
auto arr = std::experimental::make_array(1, 2, 3.4);
// creates array of ints
auto ra = std::experimental::make_array<int> (1, 2, 3.4);
ideone runnable sample
What is the rationale behind such a requirement?
The restriction is required to meet the semantics of the array container.
For example, cppreference puts it like this …
This container is an aggregate type with the same semantics as a struct holding a C-style array T[N]
as its only non-static data member.
Obviously there's no way to have a C-style array of more than one type T.
For another perspective: cplusplus says this …
Container properties
Sequence
Elements in sequence containers are ordered in a strict linear sequence. Individual elements are accessed by their position in this sequence.
Contiguous storage
The elements are stored in contiguous memory locations, allowing constant time random access to elements. Pointers to an element can be offset to access other elements.
Fixed-size aggregate
The container uses implicit constructors and destructors to allocate the required space statically. Its size is compile-time constant. No memory or time overhead.
For pointer arithmetic to make sense every element has to be the same width. For dereferencing the pointer (after pointer arithmetic) to make sense each element has to use the same bit representation - otherwise you might find yourself treating an IEEE floating point representation as if it were a two's-complement integer (or vice versa).
It doesn't really address your request for a rationale to say "because the standard says so" but it does (I think). I can't find a citeable copy of the actual standard but a working draft of the C++ standard said this...
26.3.7.2 array constructors, copy, and assignment [array.cons]
The conditions for an aggregate (11.6.1) shall be met. Class array relies on the implicitly-declared special member functions (15.1, 15.4, and 15.8) to conform to the container requirements table in 26.2. In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for array require that T be MoveConstructible or MoveAssignable, respectively.
template<class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>;`
Requires: (is_same_v<T, U> && ...)
is true. Otherwise the program is ill-formed.