https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119259
--- Comment #10 from Anders Wind <awia00 at gmail dot com> --- More interesting behavior: https://godbolt.org/z/K8cjEqTaa ``` #include <concepts> template<typename T> struct equatable { T val; // this does not constexpr bool operator==(const equatable& o)const noexcept requires(std::equality_comparable<T>){ return val == o.val; } }; template<typename T> struct default_equatable { T val; // this fails at compiling constexpr bool operator==(const default_equatable&)const noexcept requires(std::equality_comparable<T>) = default; }; struct not_equatable { int v; auto operator==(const not_equatable&) const = delete; }; template<class T> struct intermidiate { T t; constexpr inline bool operator==( const intermidiate<T>& y) const { return t == y.t; } }; int main() { auto compiles = equatable<intermidiate<not_equatable>>{.val=intermidiate<not_equatable>{{.v=42}}}; auto fails_compilation = default_equatable<intermidiate<not_equatable>>{.val=intermidiate<not_equatable>{{.v=42}}}; } ``` So implementing operator== on your own, makes gcc lazy evaluate and wont fail compilation on construction, but using = default will.