wouldn't intuitively <<20> fit char better?
Well, I think, but not according to the Standard. According to [conv.prom]p1 :
A value of an integer type other than bool , char16_t , char32_t or wchar_t , whose integer conversion rank is less than int, can be converted to prval of type int if int can represent all values ββof the source type; [...]
Now three types of characters have the same rank, and a signed type has a rank always less than int . This is a combination of [conv.rank]p1.6 and [conv.rank]p1.2
In principle, each character always has a lower rank than int , and all of them can be represented in int , so overloading with unsigned char no better, because it will be associated with converting from char to unsigned char instead of advertising.
If you change your overload to take a char , then there will be an exact match, and, of course, the βcorrectβ overload (in your eyes) will be chosen.
source share