https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107049
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #2) > template<class T> > using If_sv = enable_if_t<is_convertible<const T&, string_view>::value>; It works if this is changed to: template<class T> using If_sv = enable_if_t<__is_convertible(const T&, string_view)>; So the problem is that it fails an access check when the built-in is used outside the class body. But that should be a SFINAE context. Further reduced: template<bool B> struct bool_constant { static constexpr bool value = B; }; template<typename From, typename To> struct is_convertible : public bool_constant<__is_convertible(From, To)> { }; template<bool> struct enable_if { }; template<> struct enable_if<true> { using type = void; }; template<bool B> using enable_if_t = typename enable_if<B>::type; class Private { operator int() const; public: void f(const Private&); template<class T> enable_if_t<is_convertible<T, int>::value> f(T) { } }; int main() { Private p; p.f(p); } sfinae.cc: In instantiation of 'struct is_convertible<Private, int>': sfinae.cc:23:5: required by substitution of 'template<class T> enable_if_t<is_convertible<T, int>::value> Private::f(T) [with T = Private]' sfinae.cc:30:6: required from here sfinae.cc:6:24: error: 'Private::operator int() const' is private within this context 6 | : public bool_constant<__is_convertible(From, To)> | ^~~~~~~~~~~~~~~~~~~~~~~~~~ sfinae.cc:16:3: note: declared private here 16 | operator int() const; | ^~~~~~~~