I have a situation where I need to pass in a variable number of integers (known at compile time).
I need to achieve something like this:
template <unsigned N>
void myFunc(std::array<int, N> values)
{
// Do something useful with the values
}
I hoped the above would work and could be called like this, conveniently without creating a temporary object;
myFunc<4>({1, 2, 3, 4});
This did in fact work, but the problem is that this also works...
myFunc<4>({1, 2});
which of course leaves two of the values uninitialised, unbeknownst to me and the user.
I believe this would work:
template <unsigned N>
void myFunc(std::vector<int> values)
{
assert(values.size() == N);
// Do something useful with the values
}
myFunc<4>({1, 2}); // Goes bang
myFunc<4>({1, 2, 3, 4}); // OK
Unfortunately I can't allocate memory in my environment), so I have to do everything on the stack (and can't just accept a vector of which I could check the size).
I see myself as having two options.
- Use an object which is compile-time sized and based off of the length of the initialiser list
- Use some magic recursive C++ parameter pack syntax to allow a variable number of ints, but that's beyond me.
std::array<int, 4> arr{ 0, 1};is fine; the elements that aren't specified are simply zero-initialized. If you don't want this to work,std::arrayisn't the right class to use for you (or to be more precise: you cannot have it impose the desired restrictions).You could of course create a variadic template and restrict the parameters according to your requirements:
Why specify the number of elements multiple times though? Just use C++17's functionality doing CTAD and deduce the template parameter of the function based on the argument type:
or avoid the necessity of using a template by simply using an
std::initializer_list<int>as function parameter: