Рассмотрим эту программу:
#include <iostream>
using namespace std;
void f(unsigned char c) {
cout << c << endl;
}
void f(int c) {
cout << c << endl;
}
int main() {
f('a');
}
Это распечатывает 97
, предполагая, что f()
была выбрана перегрузка, которая int
, Я нахожу это странным; не будет интуитивно unsigned char
лучше подходить для char
?
не будет интуитивно
unsigned char
лучше подходить дляchar
?
Ну, я думаю, но не в соответствии со стандартом. В соответствии с [conv.prom]p1
:
Значение типа integer, отличного от
bool
,char16_t
,char32_t
, или жеwchar_t
чей ранг целочисленного преобразования меньше, чем ранг целого, может быть преобразован в тип значенияint
еслиint
может представлять все значения типа источника; […]
Теперь три типа символов имеют одинаковый ранг, а тип со знаком имеет ранг всегда меньше int
, Это сочетание [conv.rank]p1.6
а также [conv.rank]p1.2
:
Ранг целочисленного типа со знаком должен быть больше ранга целочисленного типа со знаком меньшего размера.
- […]
Звание
char
равняется званиюsigned char
а такжеunsigned char
,
По сути, каждый персонаж всегда имеет меньший ранг, чем int
и все они могут быть представлены в int
и так перегрузка с unsigned char
не лучшее совпадение, потому что это будет включать в себя преобразование из char
в unsigned char
вместо продвижения по службе.
Если вы измените свою перегрузку, чтобы принять char
тогда будет точное совпадение, и, естественно, будет выбрана «правильная» перегрузка (на ваш взгляд).
Других решений пока нет …