Saya bermain-main dengan c ++ 20 consteval di GCC 10 dan menulis kode ini
#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;
}
}
Yang seharusnya berfungsi seperti algoritma pencarian STL tetapi pada tupel dan bukannya mengembalikan iterator, ia mengembalikan indeks opsional berdasarkan predikat waktu kompilasi. Sekarang kode ini dikompilasi dengan baik dan tercetak
9
Tetapi jika tuple tidak mengandung elemen yang merupakan tipe integral, program tidak mengkompilasi, karena i.value () masih dipanggil pada opsional kosong. Sekarang kenapa begitu?
c++
c++20
if-constexpr
Yamahari
sumber
sumber
Jawaban:
Ini hanya bagaimana constexpr jika berfungsi. Jika kita periksa [stmt.if] / 2
penekanan milikku
Jadi kita dapat melihat bahwa kita hanya tidak mengevaluasi ekspresi yang dibuang jika kita berada dalam templat dan jika kondisinya tergantung pada nilai.
main
bukan templat fungsi sehingga isi pernyataan if masih diperiksa oleh kompiler untuk kebenaran.Cppreference juga mengatakan ini di bagian mereka tentang constexpr jika dengan:
sumber
i.value_or(0)
)