Почему самое отрицательное значение 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 ответов


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

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

может быть десятичный-литерал,

десятичный-литерал:
        ненулевой цифры
        десятичный-литерал ’ 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)допустимыми. Ваш компилятор должен выпустить компилятор ошибка о неоднозначных перегрузках.


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


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

Largest signed int




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



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

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