Я читаю стандарт и пытаюсь выяснить, почему этот код не будет решен без приведения.
void foo(char c) { }
// Way bigger than char
void foo(unsigned long int) { }
int main()
{
foo(123456789); // ambiguous
foo((unsigned long int) 123456789); // works
}
Вот что это говорит:
4.13 Целочисленный конверсионный ранг [conv.rank]
Для каждого целочисленного типа определен ранг целочисленного преобразования
следующее:— ранг любого целого типа без знака должен равняться рангу
соответствующий целочисленный тип со знаком.— ранг чар равняется званию подписанного чарса и без знака
голец.
В частности, что меня раздражает, так это то, что в нем нет НИКАКОГО беззнакового целочисленного типа, просто беззнаковый символ. Я предполагаю, что char преобразуется в тип unsigned через преобразование. Это правда?
Это имеет мало общего с рангом типа, определенного в 4.13. 4.13 определены внутренние рейтинги, используемые для описания интегральных повышений и обычных арифметических преобразований. Они сами по себе напрямую не влияют на разрешение перегрузки. Ранжирование, относящееся к разрешению перегрузки, определено в «13.3.3.1.1 Стандартные последовательности преобразования», а затем используется в «13.3.3.2 Ранжирование последовательностей неявного преобразования».
Таким образом, речь идет о степени конверсии, определенной в 13.3. 123456789
целочисленный литерал типа int
на вашей платформе. Это означает, что вызов обоих char
а также unsigned long
версии вашей функции требуют неявного преобразования из int
в char
или из int
в unsigned long
, В обоих случаях мы имеем преобразования типа «интегральное преобразование». Это означает, что в этом случае обе функции одинаково «плохие». Отсюда и двусмысленность.
Если одна из этих функций требует простого интеграла продвижение (в отличие от интегрального преобразование), он выиграет резолюцию и вызов будет считаться однозначным. Но увы обе ваши функции требуют интегрального преобразования.