Can you use C++11 variadic templates to complete /* ??? */
in:
template<bool...v> struct var_and { static bool constexpr value = /* ??? */; };
so that var_and<v...>::value
provides &&
over the boolean pack v
at compile-time?
Can you do the same for struct var_or<v...>
for ||
?
Can you use short-circuit evaluation (in both cases)?
Edit: An update to the accepted answer added that C++17 fold expressions enable
template<bool... v> constexpr bool var_and = (v && ...);
template<bool... v> constexpr bool var_or = (v || ...);
It seems that, for parameter pack-based approaches, only a restricted type of "short-circuit evaluation" is possible: while instantiating var_or<true,foo(),bar()>
only calls ||
once, it also calls both foo
and bar
.
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. However, variadic templates help to overcome this issue.
Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.
To access variadic arguments, we must include the <stdarg. h> header.
Pack expansion A pattern followed by an ellipsis, in which the name of at least one parameter pack appears at least once, is expanded into zero or more comma-separated instantiations of the pattern, where the name of the parameter pack is replaced by each of the elements from the pack, in order. template<class...
You don't want value
to be a typedef.
template<bool head, bool... tail>
struct var_and {
static constexpr bool value = head && var_and<tail...>::value;
};
template<bool b> struct var_and<b> {
static constexpr bool value = b;
};
Obviously the same can be done for ||
.
Short circuit evaluation doesn't matter because this only deals with constant expressions which won't have any side effects.
Here's another method which stops recursively generating types as soon as it find a false value, emulating a kind of short circuiting:
template<bool head, bool... tail>
struct var_and { static constexpr bool value = false; };
template<bool... tail> struct var_and<true,tail...> {
static constexpr bool value = var_and<tail...>::value;
};
template<> struct var_and<true> {
static constexpr bool value = true;
};
Update for C++17: Using a fold expression makes this much simpler.
template<bool...v> struct var_and {
static constexpr bool value = (v && ...);
};
Or also using a template variable as enobayram suggests:
template<bool... b> constexpr bool var_and = (b && ...);
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