My goal is to write a function that:
- is callable at compile time
- takes a template argument
Tuplethat represents an arbitrary std::tuple - takes a template argument
Matchthat represents the type to test for - returns true if the tuple has 1+ element of type Match
I'm on GCC 10.2, which I can upgrade if needed. I could also switch to Clang. I'm avoiding Boost, but also starting to feel like its inclusion in my project is inevitable.
If C++20 would allow the idx variable as a compile-time constant, I would be done. However, that didn't make it into the standard:
template<typename Tuple, typename Match>
consteval bool tuple_holds()
{
constexpr std::size_t size = std::tuple_size<Tuple>::value;
constexpr auto all = std::ranges::iota_view{std::size_t{0}, size};
for (const auto idx : all) {
// This doesn't work, as idx is not available as a compile-time constant
using Type = std::tuple_element<idx, Tuple>::type;
if (std::is_same<Type, Match>::value) {
return true;
}
}
return false;
}
using A = std::tuple<float, int>;
int main()
{
static_assert(tuple_holds<A, int>());
static_assert(tuple_holds<A, float>());
}
I suspect the answer lies in SFINAE, but I'm unsure of how to get further.