Je déconnais avec c ++ 20 consteval dans GCC 10 et écrivais ce code
#include <optional>
#include <tuple>
#include <iostream>
template <std::size_t N, typename Predicate, typename Tuple>
consteval std::optional<std::size_t> find_if_impl(Predicate&& pred,
Tuple&& t) noexcept {
constexpr std::size_t I = std::tuple_size_v<std::decay_t<decltype(t)>> - N;
if constexpr (N == 0u) {
return std::nullopt;
} else {
return pred(std::get<I>(t))
? std::make_optional(I)
: find_if_impl<N - 1u>(std::forward<decltype(pred)>(pred),
std::forward<decltype(t)>(t));
}
}
template <typename Predicate, typename Tuple>
consteval std::optional<std::size_t> find_if(Predicate&& pred,
Tuple&& t) noexcept {
return find_if_impl<std::tuple_size_v<std::decay_t<decltype(t)>>>(
std::forward<decltype(pred)>(pred), std::forward<decltype(t)>(t));
}
constexpr auto is_integral = [](auto&& x) noexcept {
return std::is_integral_v<std::decay_t<decltype(x)>>;
};
int main() {
auto t0 = std::make_tuple(9, 1.f, 2.f);
constexpr auto i = find_if(is_integral, t0);
if constexpr(i.has_value()) {
std::cout << std::get<i.value()>(t0) << std::endl;
}
}
Qui est censé fonctionner comme l'algorithme de recherche STL mais sur des tuples et au lieu de renvoyer un itérateur, il retourne un index facultatif basé sur un prédicat de temps de compilation. Maintenant, ce code se compile très bien et il s'imprime
9
Mais si le tuple ne contient pas d'élément de type intégral, le programme ne compile pas, car i.value () est toujours appelé sur une option vide. Maintenant, pourquoi ça?