Ich lerne etwas über Funktionsüberladung in C ++ und bin auf Folgendes gestoßen:
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);
}
Soweit ich verstanden habe, wird jeder im int
Bereich angegebene Wert (in meinem Fall int
4 Byte) aufgerufen display(int)
und jeder Wert außerhalb dieses Bereichs ist mehrdeutig (da der Compiler nicht entscheiden kann, welche Funktion aufgerufen werden soll). Sie gilt für den gesamten Wertebereich mit int
Ausnahme des Mindestwerts, dh -2147483648
wenn die Kompilierung mit dem Fehler fehlschlägt
Anruf überladen
display(long int)
ist mehrdeutig
Aber den gleichen Wert zu nehmen und den Wert zu int
drucken, ergibt 2147483648
. Ich bin buchstäblich verwirrt mit diesem Verhalten.
Warum wird dieses Verhalten nur beobachtet, wenn die negativste Zahl übergeben wird? (Das Verhalten ist das gleiche, wenn a short
verwendet wird -32768
- in jedem Fall, wenn die negative und die positive Zahl dieselbe binäre Darstellung haben.)
Verwendeter Compiler: g ++ (GCC) 4.8.5
quelle
call of overloaded ‘display(long int)’ is ambiguous
.typeof(-2147483648) != int
. Das Literal ist2147483648
, was zu groß für ein istint
, also ist es einlong
, und es wird negiertint j{-2147483648};
es sich um eine engere Konvertierung handelt. Fast eine Frage an sich wert, das. Es hängt wahrscheinlich damit zusammen, dass (z. B.)long long
Constexpr-Werte zugelassen werden2147483647LL
, um sie bei der Initialisierung einzugrenzen .Antworten:
Dies ist ein sehr subtiler Fehler. Was Sie sehen, ist eine Folge davon, dass es in C ++ keine negativen Ganzzahlliterale gibt. Wenn wir uns [lex.icon] ansehen, erhalten wir ein ganzzahliges Literal .
kann ein Dezimal-Literal sein ,
wo Ziffer ist
[0-9]
und ungleich Null stelligen ist[1-9]
und das Suffix par kann einer der folgenden seinu
,U
,l
,L
,ll
, oderLL
. Nirgendwo hier wird es-
als Teil des Dezimalliteral aufgenommen.In §2.13.2 haben wir auch:
(Hervorhebung von mir)
Was bedeutet, dass das
-
In-2147483648
das Unäre istoperator -
. Das heißt,-2147483648
wird tatsächlich als behandelt-1 * (2147483648)
. Da2147483648
es für Sie eins zu vielint
ist, wird es zu einem befördertlong int
und die Mehrdeutigkeit ergibt sich daraus, dass es nicht übereinstimmt.Wenn Sie den minimalen oder maximalen Wert für einen Typ auf tragbare Weise erhalten möchten, können Sie Folgendes verwenden:
quelle
-2147483647 - 1
würde auch ohne Vorwarnung als negativer wörtlicher Ausdruck funktionierenINT_MIN
für die am wenigsten ausführliche Option. Weniger allgemein.display(2147483649);
. Warum kann es in diesem Fall nicht die vorzeichenlose int func aufrufen? und warum behandelt es das Argument2147483649
als long int statt unsigned int?int
bislong int
nachlong long int
. Sie erhalten niemals einen vorzeichenlosen Typ für ein Dezimalliteral, es sei denn, Sie verwenden das Suffixu
/U
.display(unsigned a)
, benötigen Sie entwederdisplay(1234u);
oderdisplay(static_cast<unsigned>(1234));
oderunsigned foo = 1234; display(foo);
Der Ausdruck
-2147483648
wendet den-
Operator tatsächlich auf die Konstante an2147483648
. Auf Ihrer Plattformint
kann nicht gespeichert werden2147483648
, es muss durch einen größeren Typ dargestellt werden. Daher wird der Ausdruck-2147483648
nichtsigned int
als größerer vorzeichenbehafteter Typ abgeleitetsigned long int
.Da Sie
long
dem Compiler keine Überladung bereitstellen , muss er zwischen zwei Überladungen wählen, die beide gleich gültig sind. Ihr Compiler sollte einen Compilerfehler über mehrdeutige Überladungen ausgeben.quelle
Die Antworten anderer erweitern
Um zu verdeutlichen, warum das OP verwirrt ist, betrachten Sie zunächst die
signed int
binäre Darstellung von2147483647
unten.Fügen Sie als Nächstes eine zu dieser Nummer hinzu : Geben Sie eine weitere
signed int
an-2147483648
(die das OP verwenden möchte).Endlich: Wir können sehen, warum das OP beim
-2147483648
Kompilieren zu along int
anstelle von a verwirrt istsigned int
, da es eindeutig in 32 Bit passt.Wie in den aktuellen Antworten erwähnt, wird der unäre Operator (
-
) nach dem Auflösen angewendet ,2147483648
der a istlong int
und NICHT in 32 Bit passt.quelle