I'm creating a variadic template.
Let's say I have something like this:
template<typename T, T ... Numbers>
class Sequence final {
// Unpack parameter pack into a constexpr array
constexpr static T count = sizeof...(Numbers);
constexpr static T numbers[count] = { Numbers... };
// ...
}
Instances of this class can be instantiated like:
Sequence<uint32_t, 1, 2, 3, 42, 25> seq;
I'd like to make sure at compile time using a static_assert that the numbers parameter pack only contains specific numbers. For the sake of this example, let's say I only want to allow 0 or 1.
So I'd like to do something like:
for (size_t i = 0; i < count; i++) {
static_assert(numbers[i] == 1 || numbers[i] == 0, "Only ones and zeroes are allowed.");
}
But obviously, static_assert doesn't work with a for loop. I'm pretty sure there must be some sort of syntax for this but I haven't been able to figure it out.
I'd prefer to use something that compiles with a C++11 compiler (or perhaps a C++14 compiler, if it isn't doable in C++11).
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
I'll throw in @Columbo's bool_pack trick.
template<bool...> struct bool_pack;
template<bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
static_assert(all_true<(Numbers == 0 || Numbers == 1)...>::value, "");
Extract the expression into a constexpr function if it gets complex.
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