Reputation: 683
I'm trying to write a container class for vector arithmetic. The objects are static in size:
template<typename T, unsigned N>
class vec{
T data[N] = {0};
public:
vec(std::initializer_list<T> ini){
std::copy(ini.begin(), ini.end(), data);
}
}
This is how far I got.
But than I tested the std::array class for comparison and I noticed that it somehow could make a static assertion if the initializer list was to long or to short.
std::array<float, 2> a = {1, 2, 3, 4} <- instant error message from the visual studio ide
In my class I would have to check the length of the initializer list at run-time.
I assume, that the std::array class somehow manages it to directly initialize the data with the initializer list notation without the std::initializer_list class.
Is it possible to initialize my class in the same way as std::array?
Upvotes: 2
Views: 205
Reputation: 158459
std::array is an aggregate and so it uses aggregate initialization. Providing excess elements during aggregate initialization is ill-formed and requires a diagnostic. The compiler at minimum has to provide a warning, both gcc and clang make this an error. So if you make your class an aggregate then you can have it work the same way std::array does. Note, in class member initializers makes your class a non-aggregate in C++11 but not in C++14.
We can see it is an aggregate by going to the draft C++11 standard section 23.3.2.1
[array.overview]:
An array is an aggregate (8.5.1) that can be initialized with the syntax
array<T, N> a = { initializer-list };
where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.
and section 8.5.1
[dcl.init.aggr] covers aggregate intialization and says:
An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.
The draft standard provides for exposition a possible implementation which shortened to the bare minimum looks like this:
template <class T, size_t N>
struct array {
T elems[N];
};
and the draft standard has a note which says:
The member variable elems is shown for exposition only, to emphasize that array is a class aggregate. The name elems is not part of array’s interface
which is an aggregate and will with both gcc and clang provide an error if excess elements are provided.
Also see What are Aggregates and PODs and how/why are they special?.
Upvotes: 2