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.

Reply via email to