Ich habe etwas über Funktionsüberladung in C++ gelernt 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 Wert im Bereich int
(in meinem Fall ist int
4 Byte) display(int)
aufrufen, und jeder Wert außerhalb dieses Bereichs wird mehrdeutig sein ( da der Compiler nicht entscheiden kann, welche Funktion er aufruft). Sie gilt für den gesamten Wertebereich von int
, mit Ausnahme des Mindestwerts, d. H. -2147483648
, Bei dem die Kompilierung mit dem Fehler fehlschlägt
aufruf von überladenem
display(long int)
ist mehrdeutig
Wenn Sie jedoch den gleichen Wert auf ein int
setzen und den Wert ausdrucken, erhalten Sie 2147483648
. Ich bin buchstäblich mit diesem Verhalten verwechselt.
Warum wird dieses Verhalten nur beobachtet, wenn die negativste Zahl übergeben wird? (Das Verhalten ist dasselbe, wenn ein short
mit -32768
Verwendet wird - in der Tat in jedem Fall, in dem die negative Zahl und die positive Zahl dieselbe Binärdarstellung haben.)
Verwendeter Compiler: g ++ (GCC) 4.8.5
Dies ist ein sehr subtiler Fehler. Was Sie sehen, ist eine Folge davon, dass es in C++ keine negativen Integer-Literale gibt. Wenn wir uns [Lex.icon] ansehen, erhalten wir ein Integer-Literal ,
Integer-Literal
Dezimal-Literal-Integer-Suffixopt
[...]
kann ein Dezimal-Literal sein,
Dezimal-Literal:
Ziffer ungleich Null
Dezimal-Literal opt Ziffer
wobei Ziffer [0-9]
und Ziffer ungleich Null ist [1-9]
Und das Suffix par können entweder u
, U
, l
, L
, ll
oder LL
. Nirgendwo hier ist -
Als Teil des Dezimal-Literal enthalten.
In §2.13.2 haben wir auch:
Ein Integer-Literal ist eine Folge von Ziffern ohne Punkt oder Exponent, wobei einzelne Anführungszeichen bei der Bestimmung des Werts ignoriert werden können. Ein Integer-Literal kann ein Präfix haben, das seine Basis angibt, und ein Suffix, das seinen Typ angibt. Die lexikalisch erste Ziffer der Ziffernfolge ist die signifikanteste. Ein dezimales ganzzahliges Literal (Basis zehn) beginnt mit einer anderen Ziffer als 0 und besteht aus einer Folge von Dezimalstellen.
(Hervorhebung von mir)
Was bedeutet, dass der -
In -2147483648
Der unäre operator -
Ist. Das bedeutet, dass -2147483648
Tatsächlich als -1 * (2147483648)
behandelt wird. Da 2147483648
Eins zu viel für Ihr int
ist, wird es zu einem long int
Befördert, und die Mehrdeutigkeit ergibt sich daraus, dass es nicht übereinstimmt.
Wenn Sie den minimalen oder maximalen Wert für einen Typ portabel abrufen möchten, können Sie Folgendes verwenden:
std::numeric_limits<type>::min(); // or max()
Der Ausdruck -2147483648
Wendet tatsächlich den Operator -
Auf die Konstante 2147483648
An. Auf Ihrer Plattform kann int
2147483648
Nicht speichern. Es muss durch einen größeren Typ dargestellt werden. Daher ist der Ausdruck -2147483648
Nicht signed int
, Sondern ein größerer vorzeichenbehafteter Typ, signed long int
.
Da Sie für long
keine Überladung angeben, muss der Compiler zwischen zwei Überladungen wählen, die beide gleichermaßen gültig sind. Ihr Compiler sollte einen Compilerfehler über mehrdeutige Überladungen ausgeben.
Erweitere die Antworten anderer
Um zu klären, warum das OP verwirrt ist, betrachten Sie zuerst das signed int
binäre Darstellung von 2147483647
unten.
Fügen Sie als Nächstes eine Nummer zu dieser hinzu : Geben Sie eine weitere signed int
von -2147483648
(das das OP verwenden möchte)
Endlich: Wir können sehen, warum das OP verwirrt ist, wenn -2147483648
kompiliert zu einem long int
anstelle einer signed int
, da es eindeutig in 32 Bit passt.
Aber, wie die aktuellen Antworten erwähnen, der unäre Operator (-
) wird angewendet after2147483648
die ein long int
und passt NICHT in 32 Bits.