Deklarowanie zmiennej z dwoma typami: „int char”


81

Jestem początkującym C ++ i czytam Bjarne Stroustrup's Programming: Principles and Practice Using C ++ .

W sekcji 3.9.2 Niebezpieczne konwersje , wspomniał autor

Gdy inicjalizator jest literałem liczby całkowitej, kompilator może sprawdzić rzeczywistą wartość i zaakceptować wartości, które nie oznaczają zawężenia:

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

Zdziwi mnie ta deklaracja. Używa dwóch typów ( inti char). Nigdy wcześniej nie widziałem takiej deklaracji w Javie i Swifcie (dwóch językach, które stosunkowo dobrze znam). Czy to pomyłka czy prawidłowa składnia C ++?


2
Jakie masz wydanie i druk książki? Czy szukałeś erraty w książce?
Jakiś programista,

2
Więc jaką wersję czytasz? Jestem pewien, że Bjarne chciałby wiedzieć o tym błędzie.
StoryTeller - Unslander Monica

1
3.9.2 Niebezpieczne konwersje Przez niebezpieczną konwersję rozumiemy, że wartość może zostać niejawnie zamieniona na wartość innego typu, która nie jest równa wartości oryginalnej. np .: int i = 20000; char c = i; Takie konwersje nazywane są konwersjami „zawężającymi”. double to int, char lub bool int to char lub bool char to bool
Marichyasana

15
Jest float charto kolejny przydatny typ, szczególnie w basenach. Niektóre są wyposażone w uchwyt na piwo.
Yakk - Adam Nevraumont

1
Czy to pomyłka czy prawidłowa składnia C ++? Spróbuj (OK, OK, nie, to nieważne).
Paul Sanders,

Odpowiedzi:


95

To błąd w książce. To nie jest prawidłowa deklaracja C ++, nawet bez rzekomej konwersji zawężającej.

Nie ma o tym wzmianki w żadnej z errat na stronie Bjarne Stroustrupa (czwarty druk i wcześniejsze), co jest dziwne. To wystarczająco jasny błąd. Wyobrażam sobie, że skoro jest to skomentowane, //errorniewiele osób zauważy błąd w samej deklaracji.


Jaki był prawdopodobnie zamierzony przykład kodu w książce?
Pedro A,

8
@Hamsterrific char b1 {1000};(ponieważ spowodowałoby to błąd wspomniany w komentarzu). Chyba palce Bjarne'a były zmęczone tego dnia.
Paul Sanders,

1
@PaulSanders Zmęczony? Wpisał inttam dodatkowy ! :-)
Leo

1
@ LeoHeinsaar Lol. OK, więc za dużo kawy :) A może się zacina :)
Paul Sanders.

Tak: zmęczone palce. Wygląda na błąd „wytnij i wklej” z przykładu, który go poprzedził. W poprzednim przykładzie podaje dwie linie: int a {1000}; // OK [\ n] char b {a} // błąd: int -> char może zawęzić [\ n] i wygląda na to, że wyciął i wkleił ten przykład do następnego i nie mógł usunąć części "int" : int char b1 {1000}; // błąd: zawężanie (zakładając 8-bitowe znaki) [\ n] char b2 {48}; // OK [\ n]
L. Scott Johnson

24

Książka jest zła.

Sekwencja tokenów int char b1{1000};nie jest poprawna semantycznie C ++.

Próbujesz zadeklarować b1więcej niż jeden typ, co nie ma sensu.


10

To jest złe. W C / C ++ deklaracje wielu typów można uzyskać za pomocą unii. Na przykład:

union {
    int i;
    char c;
} var;

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

Pamięć jest taka sama, więc .c i .i są po prostu uchwytami typu dla tej samej wartości.


6

To jest błąd w składni C / C ++. Oprócz unions (patrz odpowiedź @Alex), istnieje sposób w C ++ na przechowywanie tylko jednego z dostępnych typów o nazwie std::variant(type-safe union):

#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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.