It doesn't actually pick the second overload. The problem is that std::tuple_element_t
apparently is not SFINAE-friendly.
Merely checking that overloaded requires calling std::tuple_element_t<2, std::tuple<int, float>>
, which fails on a static_assert
, which is not something SFINAE can recover from.
Make your own wrapper that fails in a SFINAE-friendly way:
template <std::size_t I, typename T>requires (I < std::tuple_size<T>::value)using my_tuple_element = std::tuple_element_t<I, T>;
And use my_tuple_element
instead of std::tuple_element_t
.
Side note: std::tuple_size_v<T>
is infamously not SFINAE-friendly (fails on non-tuple-like types), but std::tuple_size<T>::value
is.