Reputation: 52331
I have a template class where the template parameter corresponds to the size of an array within the class.
template <typename T, size_t S>
class Example {
...
private:
T values[S];
};
This leads to an expected warning: “ISO C++ forbids zero-size array.” In my case, something like Example<uint8_t, 0>
would make no sense, and I would like to prevent the code containing Example<..., 0>
from compiling.
How do I express in C++ that S
should be superior or equal to one?
Upvotes: 8
Views: 513
Reputation: 264571
If there are situations where S being zero are valid. You can add a specialization for that case.
template<typename T, size_t S>
class Example {
...
private:
T values[S];
};
template<typename T>
class Example<T, 0> {
...
private:
// Don't need an array here for this case.
};
This will keep your code compiling in situations where you have heavy templating that makes S zero.
Upvotes: 2
Reputation: 96579
The C++20 way is
template <typename T, size_t S> requires (S > 0)
class Example
{
// ...
};
Upvotes: 12
Reputation: 118445
You're really trading in one compiler diagnostic for another, but here's one approach:
template <typename T, size_t S,
typename=std::enable_if_t< (S>0) >>
Alternatively: use static_assert
to get a friendlier error message:
template <typename T, size_t S>
class Example {
private:
static_assert(S>0);
T values[S];
};
You'll get a friendlier error message however this template will still participate in overload resolution, which in some edge cases may be undesirable.
Upvotes: 8
Reputation: 238401
T values[0];
is alread ill-formed. Thus, if you configure the compiler to not use language extensions, then it won't compile.
Or, you can use a static_assert
.
Upvotes: 4