Frage Eine Variable mit zwei Typen deklarieren: "int char"


Ich bin ein C ++ Anfänger und lese gerade Bjarne Stroustrups Programmierung: Prinzipien und Praxis mit C ++.

Im Abschnitt über 3.9.2 Unsichere Konvertierungen, der Autor erwähnt

Wenn der Initialisierer ein Integer-Literal ist, kann der Compiler den tatsächlichen Wert überprüfen und Werte akzeptieren, die keine Verengung bedeuten:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)

Ich bin verwirrt über diese Erklärung. Es verwendet zwei Arten (int und char). Ich habe noch nie eine solche Erklärung in Java und Swift gesehen (die beiden Sprachen, mit denen ich relativ vertraut bin). Ist das ein Tippfehler oder eine gültige C ++ - Syntax?


75
2017-07-09 06:53


Ursprung


Antworten:


Es ist ein Fehler in dem Buch. Das ist keine gültige C ++ - Deklaration, auch ohne die angeblich einschränkende Konvertierung.

Es wird in keinem der erratas auf erwähnt Bjarne Stroustrups Seite(4. Druck und früher), aber das ist seltsam. Es ist ein klarer Fehler. Ich stelle mir vor, da es kommentiert wurde //error Wenige Menschen bemerken den Fehler in der Erklärung selbst.


91
2017-07-09 06:56



Das Buch ist falsch.

Die Token-Sequenz int char b1{1000}; ist nicht semantisch gültig C ++.

Sie versuchen zu deklarieren b1 mit mehr als einem Typ, was keinen Sinn macht.


22
2017-07-09 06:55



Es ist falsch. In C / C ++ können die Multi-Typ-Deklarationen über die Verwendung von Unionen erreicht werden. Z.B:

union {
    int i;
    char c;
} var;

var.i = 42;
/* OR */
var.c = ‘c’;

Der Speicher ist derselbe, also sind .c und .i nur per-type-Handles auf den gleichen Wert.


10
2017-07-10 06:41



Das ist in der C / C ++ - Syntax falsch. In Abhängigkeit von unions (siehe @Alex Antwort), gibt es C ++ Möglichkeit, nur einen der verfügbaren Typen zu speichern std::variant (typsichere Vereinigung):

#include <variant>
#include <string>

int main()
{
    std::variant<int, float> v, w;
    v = 12; // v contains int
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // same effect as the previous line
    w = v; // same effect as the previous line

//  std::get<double>(v); // error: no double in [int, float]
//  std::get<3>(v);      // error: valid index values are 0 and 1

    try {
      std::get<float>(w); // w contains int, not float: will throw
    }
    catch (std::bad_variant_access&) {}

    std::variant<std::string> v("abc"); // converting constructors work when unambiguous
    v = "def"; // converting assignment also works when unambiguous
}

6
2017-07-13 08:24