I don't know what libraries you are using, but something like the + operator in C++ is still used mostly for number and string like objects. I rarely see misuses of operator overloading these days. But that's beside the point. Yes, when you see hs.add(elem), it's obvious it belongs to hs. But you still don't know what hs or elem is unless you look it up. But in C, you do not have member functions. You have free functions add(hs, elem). And if the person decided that their library requires that add(...) work with a multitude of types, they would make the arguments tagged structs or void pointers, leaving you with even more cognitive strain to look at all the different conditional states in the add(...) function that handle all the different combinations of types explicitly. And that also doesn't guarantee that inside the add(...) function it treats all possible combinations of arguments with equivalent semantics.
Not to mention that, actually, C has some implicit operator overloading as well. You can add pointers and integers together and it behaves differently to adding integers. You will have to look up the actual types of the operands to figure out what the semantics are and that has caught out many good programmers.
For any complex software libraries, whether written in C++ or C, I have never encountered one where I never needed to keep referring to the types of the operands anyway, so the cognitive strain is mostly equivalent.