I am using std::array<size_t, N>
(N is a fixed template-variable).
#include<array>
template<size_t N>
struct A{
size_t function(std::array<size_t, N> arr){ return arr[N-1];} // just an example
};
int main(){
A<5> a;
a.function({{1,2,3,4,5}}));
}
And it works fine. The problem is that this other code is silently allowed:
A.function({{1,2,3}}));
That is, even with missed elements the array
is initialized somehow, even if it is well defined (e.g. remaining elements initialized to zero, I am not sure) this is a possible source of errors.
Is there a way to enforce the initialization of the extra elements? E.g. by generating a compiler error or a warning.
One option that I contemplated is to use initializer_list
size_t function2(std::initializer_list<size_t> il){ assert(il.size() == N); ...}
The problem is that this generated a runtime error at best and a check in every call. I would prefer a compiler error/warning.
I am not so much bothered by the default initialization of std::array<>{}
but by the incomplete initialization. (Maybe there is nothing it can be done about it, since this is inherited from the behavior of T[N]
static array.)
I tried using clang 3.5
and gcc 5
.
You can enforce this by using parameter pack, but with a bit different syntax:
#include <array>
template<size_t N>
struct A{
template<typename... T>
size_t function(T&&... nums)
{
static_assert(sizeof...(nums) == N, "Wrong number of arguments");
std::array<size_t, N> arr = { std::forward<size_t>(nums)... };
return arr[N-1];
}
};
int main(){
A<5> a;
a.function(1,2,3,4,5); // OK
a.function(1,2,4,5); // Compile-time error
}
But, I think there is no good way to enforce that in compile time. I would just use assert(il.size() == N)
in production code to check size of initializer list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With