https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115285
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #7) > I am suspecting it was > https://gcc.gnu.org/git/?p=gcc.git;a=commit; > h=2c43f5ec9db163696de8691eb529df06c4999bcc which caused the issue. Ah no, I think you're right about this. The problem is not std::equal_to, but in std::hash<TrimmedStr>, because it takes an argument of type std::string not TrimmedStr. This means that hashing "foo "s does not convert to a TrimmedStr first, so it hashes the un-trimmed string. This fixes the code: template<> struct hash<TrimmedStr> { bool operator()(const TrimmedStr& s) const noexcept { return std::hash<std::string>{}(s); } }; I'm not sure if the code is valid or not. It certainly seems like a problem that a plain std::string can be compared to a TrimmedStr using std::equal_to<TrimmedStr> *and* can be hashed using std::hash<TrimmedStr>, when a plain std::string is *not* a TrimmedStr. Using inheritance this way is a bad idea, certainly for the std::hash specialization. IMHO also for the TrimmedStr itself.