Numeric_limits und Typen



  • Badestrand schrieb:

    Das kann doch aber nur als constexpr funktionieren, oder nicht? decltype(a<b?b:a) muss ja zur Compile-Zeit feststehen; wenn a und b Variablen sind, ist das wohl nicht möglich. Kann sein, dass ich da grad quer denke oder was übersehen hab, aber mir scheint das etwas obskur.. 🙂

    der returntype von ?: bestimmt sich durch integer promotion, das läuft und lief schon immer zur compilezeit.
    aber ich muss zugeben, daß ich auch ins schwitzen kam bei dem konstrukt.



  • Hast du zufällig Lust, mir das zu erklären? "Integer Promotion" hatte ich nie gehört, Google hat aber geholfen. Verstehe trotzdem nicht, wie decltype(a<b?b:a) ausgewertet wird, wie wird denn da "a<b" behandelt, etwa die Limits ihrer Typen?



  • Badestrand schrieb:

    wie wird denn da "a<b" behandelt, etwa die Limits ihrer Typen?

    Falscher Ansatz.

    a<b liefert ein bool, aber das ist fuer den decltype egal.

    Wenn ich

    short a=7;
    

    schreibe, ist es ja auch klar was passiert. 7 ist zwar ein int aber er wird zu einem short promoted mit uU einem werteverlust.

    Wenn ich nun

    3f + 7d;
    

    schreibe, dann muss der ergebnis typ ja vorher feststehen, oder? unabhaengig welche werte die beiden operanden haben. Wir wissen es: double ist das Ergebnis.

    Bei a<b?b:a ist es das selbe: das ergebnis ist ein typ der sowohl a als auch b beinhalten kann. Wir wissen ja nicht ob a oder b als ergebnis kommt, deshalb muessen wir beide speichern koennen.

    Deshalb geht auch folgendes nicht:

    double d = true ? 0.7 : "hallo";
    

    obwohl wir wissen dass immer 0.7 als ergebnis raus kommt sind char* und double dennoch inkompatibel und duerfen hier nicht verwendet werden.

    decltype(a<b?b:a)
    

    macht nun nichts anderes als den typen zu bestimmen den man braucht um sowohl a als auch b beinhalten zu koennen.

    uU ist es bei einem

    decltype(a+b)
    

    logischer?

    Ich weiss zwar nicht wieviel a+b ist, aber ich weiss dass short + int = int ist.

    Das ganze klappt natuerlich auch mit UDT:

    string a;
    char* b;
    decltype(a+b) c;
    

    c muss vom typ string sein. Denn fuer string + char* finde ich genau einen match, naemlich:

    string operator+(string const& a, char const* b);
    

    aus der string klasse.

    wenn der operator+ mehrdeutig waere, wuerde decltype einen fehler liefern.
    in prinzip ist also decltype(a+b) ja nur die kurzschreibweise fuer

    decltype(operator+(a,b))
    


  • Badestrand schrieb:

    Hast du zufällig Lust, mir das zu erklären? "Integer Promotion" hatte ich nie gehört, Google hat aber geholfen. Verstehe trotzdem nicht, wie decltype(a<b?b:a) ausgewertet wird, wie wird denn da "a<b" behandelt, etwa die Limits ihrer Typen?

    decltype(a<b?b:a) funktioniert gleich wie sizeof(a<b?b:a) - der Compiler guckt einfach was für einen Typ der Ausdruck "a<b?b:a" hat und substituiert dann den typ bzw. bei sizeof die grösse.

    es gehen ja auch so dinge wie sizeof(a+b) oder sizeof(my_function()) oder sizeof((my_class().my_function().yet_another_function() << 42) + 23) oder ...
    und eben auch mit decltype.


Anmelden zum Antworten