Tôi đã loay hoay với c ++ 20 consteval trong GCC 10 và đã viết mã này
#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;
}
}
Được cho là hoạt động giống như thuật toán tìm STL nhưng trên các bộ dữ liệu và thay vì trả về một trình vòng lặp, nó trả về một chỉ mục tùy chọn dựa trên một vị từ thời gian biên dịch. Bây giờ mã này biên dịch tốt và nó in ra
9
Nhưng nếu bộ dữ liệu không chứa một phần tử là một kiểu tách rời, chương trình sẽ không biên dịch, bởi vì i.value () vẫn được gọi trong một tùy chọn trống. Bây giờ tại sao vậy?