I would like to template a class on a possibly fixed number of bools, count them, and use that number as the template parameter to a base class. Something like this
template <int Dimensionality> struct Foo {}; // I want to inherit from this
// helpers to compile-time count the true values among bools
template <bool B, bool... Args>
struct count_true {
static constexpr int value = count_true<B>::value + count_true<Args...>::value;
};
template <>
struct count_true<true> {
static constexpr int value = 1;
};
template <>
struct count_true<false> {
static constexpr int value = 0;
};
// I want something like this, pseudocode
template <bool... Args>
struct Bar : public Foo<count_true<Args...>::value> {
Bar(bool... args) {
// do something with the parameters
static_assert(sizeof...(args) <= 1337);
}
};
But I can't find a way to do this.
There seem to be a lot of questions relating to the use of enable_if
for parameter packs for functions, e.g.
Or uses where the template types are not used for inheritance, e.g.
But none of that has helped in this particular case.
The "pseudocode" does not compile because bool... args
is not an unexpanded parameter pack.
I was thinking something like this might work, but it does not, as the parameter pack must be the last template parameter:
template <class... Ts>
struct Bar : public Foo<count_true<Ts..., std::enable_if_t<(std::is_same<Ts, bool>::value && ...), bool>>::value> {
…
}
Is there a way to accomplish this? This question is probably a bit confused, as I really don't know what I'm doing w.r.t. template metaprogramming.
But none of that has helped in this particular case. The "pseudocode" does not compile because
bool
... args is not an unexpanded parameter pack.
You can expand template parameters using decltype()
. Additionally, count_true
can be simply replaced with fold-expression.
template <bool... Args>
struct Bar : public Foo<(Args + ... + 0)> {
Bar(decltype(Args)... args) {
// do something with the parameters
static_assert(sizeof...(args) <= 1337);
}
};