I'm trying to initialize a class Vec with a brace-enclosed initializer list, to be called like in this minimal example:
int main()
{
Vec<3> myVec1{{1,2,3}}; // or: myVec1({1,2,3});
Vec<3> myVec2;
myVec2 = {1, 2, 3};
Vec<3> myVec3 = {1,2,3};
return 0;
}
All these initializations (and the assignment) should work. (Plus custom default constructor. Using an aggregate class is thus impossible.)
While I could just use a std::initializer_list like such:
template <unsigned C>
struct Vec
{
Vec(){}
Vec(std::initializer_list<int> list)
{
//does not work for obvious reasons:
//static_assert(list.size() == C, "");
}
};
I can't statically ensure the number of parameters to be equal to my template parameter, i.e., an initialization with {1, 2, 3, 4} would only fail during runtime.
Browsing SO, I came up with the following:
template <unsigned C>
struct Vec
{
Vec(){}
Vec(const unsigned(&other)[C]){}
Vec& operator=(const unsigned(&other)[C]){return *this;}
};
This works fine for the assignment and () or {} initialization (as for myVec1) - but it fails for the initialization using = (as for myVec3).
(GCC gives error "could not convert '{1, 2, 3}' from '' to 'Vec<3u>'")
I don't get why one of the initializations should work, but not the other. Any other ideas how I can use the brace-enclosed initializer list, but also ensure the correct length at compile time?
Thanks :)