diff --git a/include/iris/alloy/traits.hpp b/include/iris/alloy/traits.hpp index 0b510cce4..1f1c2bf44 100644 --- a/include/iris/alloy/traits.hpp +++ b/include/iris/alloy/traits.hpp @@ -187,12 +187,30 @@ struct basic_common_reference_impl class TQual, template class UQual> - requires (iris::is_ttp_specialization_of_v || - iris::is_ttp_specialization_of_v) && - (iris::alloy::tuple_size_v == iris::alloy::tuple_size_v) +// Note: We can't directly specify the concept `TupleLike` in the +// declaration of the template parameter because it would invoke +// the `TupleLike` check for virtually ANY types whenever the +// *primary* template of `std::basic_common_reference` is instantiated. +// +// Doing so would produce some hard errors on completely irrelevant +// context; for example, calling `std::map{}.rbegin()` would +// inevitably *check* `TupleLike` for `std::pair` thus +// leads to instantiation of `getter_of`. Then if the instantiation +// yields hard error for some reason, the error is propagated to the +// caller in SFINAE-unfriendly context. +template class TQual, template class UQual> + requires + ( + iris::is_ttp_specialization_of_v || + iris::is_ttp_specialization_of_v + ) && + iris::alloy::TupleLike && iris::alloy::TupleLike && + (iris::alloy::tuple_size_v == iris::alloy::tuple_size_v) struct std::basic_common_reference - : iris::alloy::detail::basic_common_reference_impl>> {}; + : iris::alloy::detail::basic_common_reference_impl< + TTuple, UTuple, TQual, UQual, + std::make_index_sequence> + > +{}; #endif