https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- Using std::conjunction: template<typename T> using has_begin2 = std::bool_constant<has_begin<T>>; template<typename T> struct has_nested_begin { // ill-formed unless has_begin<T> is true: static constexpr bool value = has_begin<std::remove_reference_t<decltype(*std::begin(std::declval<T>()))>>; }; template<typename T> int f(T) { if (std::conjunction_v<has_begin2<T>, has_nested_begin<T>>) return 0; return 1; } When has_begin2<T>::value is false, has_nested_begin<T>::value is not needed, so is not instantiated.