Почему самое отрицательное значение int вызывает ошибку о неоднозначных перегрузках функций?


я узнаю о перегрузке функций в C++ и наткнулся на это:

void display(int a)
{
    cout << "int" << endl;
}

void display(unsigned a)
{
    cout << "unsigned" << endl;
}

int main()
{
    int i = -2147483648;
    cout << i << endl; //will display -2147483648
    display(-2147483648);
}

насколько я понял, любое значение, указанное в элементе

3 85

3 ответа:

это очень тонкая ошибка. То, что вы видите, является следствием отсутствия отрицательных целочисленных литералов в C++. Если мы посмотрим на [Лекс.значок] мы получаем, что a integer-literal,

integer-literal
        десятичное-литеральное целое число-суффикс opt
        [...]

может быть decimal-literal,

decimal-literal:
        ненулевой цифры
        decimal-literal' opt цифры

здесь цифры и [0-9] и ненулевой цифры и [1-9] и суффикс par может быть одним из u,U,l,L,ll или LL. Нигде здесь это не включает - как часть десятичного литерала.

In §2.13.2, мы также имеем:

An целочисленный литерал - это последовательность цифр, которая не имеет периода или экспоненты, с необязательным разделением одинарных кавычек, которые игнорируются при определении его значения. Целочисленный литерал может иметь префикс, определяющий его основание, и суффикс, определяющий его тип. Лексически первая цифра последовательности цифр является наиболее значимой. A decimal целочисленный литерал (основание десять) начинается с цифры отличное от 0 и состоит из последовательности десятичных цифр.

(выделено мной)

что означает - на -2147483648 - это унарный operator -. Это значит -2147483648 на самом деле рассматриваться как -1 * (2147483648). Так как 2147483648 - это слишком много для вашего int он повышен до long int и двусмысленность исходит из того, что не соответствует.

если вы хотите получить минимальное или максимальное значение для типа переносимым способом вы можете использовать:

std::numeric_limits<type>::min();  // or max()

выражение -2147483648 на самом деле применение - оператор на постоянный 2147483648. На вашей платформе, int не могу в магазине 2147483648, он должен быть представлен большего типа. Поэтому выражение -2147483648 не выводится быть signed int но более крупный подписанный тип, вероятно signed long int.

так как вы не предоставляете перегрузку для long компилятор вынужден выбирать между двумя перегрузками, которые являются одинаково допустимыми (in). Ваш компилятор должен выпустить компилятор ошибка о неоднозначных перегрузках.

расширение на ответы других


чтобы прояснить, почему ОП путается, сначала: считать signed int двоичное представление 2147483647 ниже.

Largest signed int




Далее, добавьте к этому числу: даю еще один signed int на -2147483648 (который ОП желает использовать) Smallest signed int



и наконец: мы можем видеть, почему OP путается, когда -2147483648 компилируется в long int вместо signed int, Так как он четко вписывается в 32 бит.

но, как упоминают текущие ответы, унарный оператор (-) применяется после разрешение 2147483648 что это long int и не вписывается в 32 бита.