2017-03-23 6 views
7

Während ich über Datentyp-Konvertierung gelesen, sah ich dieses Beispiel:In C++ können wir {} für C-Style-Casting verwenden?

void intval() 
{ 
    for (char c; cin >> c;) 
    cout << "the value of '" << c << "' is " << int{c} << '\n'; 
} 

Ich weiß, dass wir mit werfen können:

  1. int(c)
  2. (int) c
  3. static_cast<int>(c)

Meine Suche Ionen:

Q1: Ist int{c} eine andere Möglichkeit zum Darstellen von Datentypen?

Q2: Nach einigen Nachforschungen im Internet weiß ich, dass C++ - Casting anders ist und der Compiler die Casting-Möglichkeit zur Kompilierzeit überprüft, aber was sind die Unterschiede zwischen 1 und 2? Und wie ist int{c} anders, wenn es nur ein anderer Casting Weg ist?

Q3: Gibt es noch andere Möglichkeiten zum expliziten Konvertieren/Cast?

+3

Ich dachte, dass die geschweiften Klammern mit der Initialisierung der Liste zu tun haben, siehe diese Antwort http://stackoverflow.com/a/18222927/3110529 TL; DR: Die Initialisierung der Liste erlaubt keine Verengung (§iso.8.5. 4) bedeutet, dass es unsichere Typkonvertierungen auffängt. – Dillanm

+0

Insbesondere, wenn "d" ist ein "double" und "double" ist die gleiche Größe wie 'uint64_t',' static_cast (d) 'und' reinterpret_cast (d) 'konvertieren auf völlig unterschiedliche Weise. C-Style-Modelle haben diese Flexibilität nicht; Sie müssten eine Union oder einen Zeiger eingeben, um die Bits neu zu interpretieren. – Davislor

Antwort

7

Ist int{c} eine andere Möglichkeit, Datentypen zu konvertieren?

Ja.T{value} erstellt ein temporäres Objekt vom Typ T, das heißt direktlisteninitialisiert mit der angegebenen braced-init-Liste. Diese Umwandlung hat gegenüber T(value) einen Vorteil, da T{value} zum Erstellen eines temporären Arrays verwendet werden kann. Das wäre wie

int main() { 
    using int_array = int[5]; 
    for(auto e : int_array{1,2,3,4,5}) 
     std::cout << e; 
} 

geschieht Es kommt auch mit dem Vorbehalt, dass eine Verengung Umwandlung ist ein Fehler

int main() { 
    int(10000000000ll); // warning only, still compiles 
    int{10000000000ll}; // hard error mandated by the standard 
} 

Nach einigen Recherchen im Netz, weiß ich, dass C++ Gießen unterschiedlich ist und es Lassen Sie den Compiler die Casting-Möglichkeit zur Kompilierzeit überprüfen, aber was sind die Unterschiede zwischen 1 und 2?

Der große Unterschied zwischen T(value) und (T)value ist, dass in T(value), T ein einzelnes Wort sein muss. Zum Beispiel

int main() { 
    unsigned int(10000000); // error 
    (unsigned int)10000000; // compiles 
} 

Q3: Gibt es noch andere Möglichkeiten, um explizit/cast-Format konvertieren?

Gut in C++ sie möchten, dass Sie die C++ wirft verwenden, die sind static_cast, reinterpret_cast, dynamic_cast und const_cast. Diese werden gegenüber der c-Stil-Umwandlung bevorzugt, da eine c-Stil-Umwandlung all jene ausführt, bei denen die C++ - Versionen bestimmte Einschränkungen haben und mit gewissen Garantien versehen sind.

3

Q1: Ja. Es ist fast das gleiche wie ein funktionaler Stil (int(c)) und funktioniert wegen C++ 11's uniform initialization. Bei der geschweiften Klammerung gibt es jedoch einige Vorbehalte, z. B. wird durch die Verringerung von Konvertierungen (wie long l = 5; char c{l};) eine Warnung generiert.

Q2: 1 und 2 sind gleichwertig, obwohl es einige Situationen gibt, in denen die eine funktioniert und nicht die andere.

// long long(c); // Breaks unless you make a typedef for 'long long' 
(long long)c; // Works fine 

template <class In, class Out> 
Out convert(const In& in) { 
    // return (Out)in; // Only works if 'In' is a primitive type 
    return Out(in); // Works regardless of the type of 'In' (assuming an appropriate constructor exists) 
} 

Q3: Das einzige Beispiel für C++ - Stil Casting, die Sie erwähnen static_cast ist. Es gibt auch andere C++ wirft auch:

  • dynamic_cast
  • reinterpret_cast
  • const_cast
5

int(c) die die C++ Version des C-Stil (int)c gegossen ist. Es versucht zuerst eine const_cast<int>(c), dann (wenn das nicht gelingt) eine static_cast<int>(c) gefolgt von reinterpret_cast.

int{c} ist ein etwas anderes Fischvieh. Streng genommen ist dies eine Listeninitialisierung und hat strengere Regeln. Insbesondere eingrenzende Konvertierungen sind nicht erlaubt, das heißt

int x; 
char s{x}; // error 

Daher empfiehlt es sich, diese zu verwenden (anstelle von Abgüssen), es sei denn Sie wissen, dass eingrenzende Konvertierungen akzeptabel sind.

Für andere als eingebaute Typen gibt es zusätzlich zu den oben genannten Modellen auch dynamic_cast.

Verwandte Themen