He performed the selective comparison used for std :: set, which compares only units, that is, the modulo 10. Since std :: set is a template, it just tries to call what looks like a function, regardless of whether it is one or no. By overloading operator (), you force it to act as a function.
Doing this can in some cases be extremely powerful, because a struct / class can save state as well as additional parameters. The whole boost :: function / boost :: bind function is based on this (and you don't need to create a class every time).
There is perhaps a slight flaw in the encoded actual example, since the exercise was just to sort them by units, but it could very well eliminate numbers that have the same units but are not actually duplicated. There are no such examples in your code example (you have a duplicate, but this is a duplicate of the whole value). If you had 3478 in addition to 4548, the comparator would consider them the same and would not allow duplication.
By the way, I'm not sure that set is what I would call a "associative" container, which refers to key-value pairs. There are no related values in the set, just keys.
Another point: operator () must be const.
source share