Consider the C++ 17 code below, which tests a set of enum values to see if another enum value is contained in that set:
enum Flag { val1, val2, val3, val4, val5 };
template<Flag arg> struct Value {
template<Flag... set> struct IsIn {
static constexpr bool value =
static_cast<bool>(((set == arg) || ...));
};
};
This works as intended:
bool x = Value<val4>::IsIn<val1, val2, val5>::value;
// x == false
bool y = Value<val2>::IsIn<val3, val2>::value;
// y == true
However, I wish to test if all of a set of values are contained within another set, like so:
template<Flag... args> struct Values {
template<Flag... set> struct AreIn {
static constexpr bool value =
static_cast<bool>((Value<args>::IsIn<set...>::value && ...));
};
};
The above does not compile on GCC 7.3 or Clang 5.0; they both give rather cryptic answers that give little insight into the problem. Given that parameter pack expansion in a template parameter list is allowed (as long as the template supports the expansion), I'm having a hard time figuring out why this isn't legal C++.