Switch i typ inny niż integralny.

0

Witam.
Dlaczego w c++ w instrukcji switch nie można użyć innego typu niż typ całkowity, tak jak ma to miejsce w innych językach?

0

Bo tak postanowił autor języka.

0

W Javie dostępne "już od" wersji 7...

1

mozna uzyc innego typu niz integralny. Ktos nawet dawal tutaj ostatnio linka mysle ze to był @kq
ale pierwszy lepszy z googla
http://stackoverflow.com/questions/16388510/evaluate-a-string-with-a-switch-in-c
Tylko ze trzeba zrobic obudowe do tego.

w C++ mozesz zrobic co Ci sie jawnie podoba. Tylko ze musisz to przedtem zbudowac

5
fasadin napisał(a):

mozna uzyc innego typu niz integralny. Ktos nawet dawal tutaj ostatnio linka mysle ze to był @kq
ale pierwszy lepszy z googla
http://stackoverflow.com/questions/16388510/evaluate-a-string-with-a-switch-in-c
Tylko ze trzeba zrobic obudowe do tego.

w C++ mozesz zrobic co Ci sie jawnie podoba. Tylko ze musisz to przedtem zbudowac

Tak: http://dev.krzaq.cc/switch-on-strings-with-c11/

Przy czym niestety to raczej zabawa z językiem a nie faktyczne rozwiązanie problemu. No ale jeśli jesteś pewien, że unikniesz kolizjii hasha (co jest kłopotliwe, bo ASCII/UTF-8 nie jest gwarantowane przez standard), to masz gwarancję, że to będzie działało poprawnie.

edit: switcha można całkiem skutecznie zasymulować kontenerem par predykat-funkcja, gdzie wykonywana jest funkcja, jeśli predykat jest prawdziwy.

A co do odpowiedzi na zadane pytanie:

  • jeśli mówimy o string literalsach - to są to po prostu tablice T const[S], gdzie T to typ znaku zależny od definicji, a S to długość stringa + 1. Tablic w C i C++ nie można porównywać za pomocą =, więc zapewne z tego powodu nie mogą być wyrażeniami w switchu.
  • jeśli mówimy o std::string to jest to "zwykła" klasa i nic poza przestrzenią nazw nie różni jej od czegoś co możesz zdefiniować sam. Wobec tego należałoby rozszerzyć pytanie do "dlaczego nie wolno używać własnych typów w switchu". Przed C++11 odpowiedzią na to pytanie było "nie można zainicjalizować klasy w czasie kompilacji". Od C++11 mamy constexpr i w sumie nie wiem dlaczego ta restrykcja została. Być może nikt o to dostatecznie głośno nie walczył? Być może chodzi o to, że kompilator nie jest w stanie dowieść, że operator== Twojej klasy nie zwróci true dla kilku case'ów?
0
kq napisał(a):
  • jeśli mówimy o std::string to jest to "zwykła" klasa i nic poza przestrzenią nazw nie różni jej od czegoś co możesz zdefiniować sam. Wobec tego należałoby rozszerzyć pytanie do "dlaczego nie wolno używać własnych typów w switchu". Przed C++11 odpowiedzią na to pytanie było "nie można zainicjalizować klasy w czasie kompilacji". Od C++11 mamy constexpr i w sumie nie wiem dlaczego ta restrykcja została. Być może nikt o to dostatecznie głośno nie walczył? Być może chodzi o to, że kompilator nie jest w stanie dowieść, że operator== Twojej klasy nie zwróci true dla kilku case'ów?

Tak, właśnie miałem na myśli własne typy.
Trochę nie rozumiem tego: "nie można zainicjalizować klasy w czasie kompilacji".
Skoro jest możliwe coś takiego:

if(obj == obj2)...

to dlaczego nie można zrobić tego tak?:

switch(obj){ case ob2:...

Oczywiście, w przypadku porównywania obiektów, trzeba by było wywołać metodę, która by te obiekty porównała, a potem wykonać skok, ale co to za problem? switch jest czymś innym, niż zwykłym skokiem warunkowym, takim jak if?

1

Warunki case'ów muszą być stałe w czasie kompilacji, inaczej ryzykujesz masakryczną niewydajność. Weź na przykład klasę Matrix reprezentującą macierz. Czy

case Matrix::ones(1000,1000):

powinno alokować kilka MB tylko do porównania jednego z wielu warunków? A co jeśli konstruktor wpływa na jakiś stan globalny? Ponadto jeszcze jest zasada unikalności wartości w case'ach - co zrobić, jeśli operator= Twojego typu jest zależny od jakiejś zmiennej globalnej? Pamiętaj, że program kompilowany jest jedno TU naraz i kompilator nie widzi większości definicji.

tl;dr: twórcy postanowili, że switch będzie miał takie ograniczenia, i zgodnie z nimi nie można łatwo switchować po dowolnym typie.

1

Zawsze możesz coś takiego zrobić:
http://ideone.com/6nQWsX

1 użytkowników online, w tym zalogowanych: 0, gości: 1