I want to implement a data structure with compile time constant size(like std::array
). I want to be able to initialize this data structure like this:
MyStruct<3, int> example = {1, 2, 3};
This work fine using constructor like: MyStruct(std::initializer_list<T> elements)
, but the compiler doesn't enforce the same size for my internal structure and elements
, even if they are both known at compile time.
I can't use static_assert
because elements.size()
is not compile time constant.
Is there any way to enforce at compile time same size for elements
as in MyStruct
?
You could try a constructor using variadic templates:
template<std::size_t N, typename E>
struct MyStruct {
int otherStuff;
E values[N];
template<typename ...TT>
MyStruct(TT&&...t) : values{std::forward<TT>(t)...} {
static_assert(N == sizeof...(t), "Size mismatch!");
for (size_t i = 0; i < N; i++) std::cout << values[i] << ",";
std::cout << std::endl;
}
};
This does work as expected with:
MyStruct<3, int> example = {1,2,3};
MyStruct<3, int> exampleFail = {1,2}; //error: static assertion failed: Size mismatch!
Please note that there is still a difference between std:array
and MyStruct
when it comes to list-initialization:
MyStruct<3, int> exampleList{1,2,3}; // works
std::array<int, 3> arr = {1,2,3}; // works, but warning with clang++
std::array<int, 3> arrList{1,2,3}; // works with g++, does not compile with clang++
The reason is, that the single brace only works for std::array because of brace elision, which does not always apply as documented in an official defect report.