link Zauważ, że nie ma znaczenia, czy int pasuje do jednej ze stałych typu wyliczeniowego; konwersja typu jest zawsze nielegalna.
Iwaz
3
Uważam, że jeśli chcesz rzutować na Test :: A, wartość int abędzie musiała wynosić 0, ponieważ Test :: A ma domyślną wartość 0, a Test :: B ma domyślną wartość 1. Chyba że fakt rzutowania specjalnie na Test :: A jest poza tym ...
@Mitch Co dostanę za korzystanie autow tym przypadku? Czy są jakieś ulepszenia wydajności?
Frederico Pantuzza
2
Brak ulepszeń wydajności. Kompilator po prostu automatycznie dedukuje typ, jeśli określisz go jako „auto”. Jeśli zdecydujesz się zmienić nazwę wyliczenia w przyszłości, będziesz modyfikować swój kod mniej, ponieważ kompilator automatycznie wydedukuje poprawną nazwę typu.
MSDN: Operator static_cast może jawnie przekonwertować wartość całkowitą na typ wyliczenia. Jeśli wartość typu całkowego nie mieści się w zakresie wartości wyliczenia, wynikowa wartość wyliczenia jest niezdefiniowana.
Kirill Kobelev
1
@KirillKobelev, jeśli wartość całki może być reprezentowana przez podstawowy typ wyliczenia, wówczas wyliczenie wynikowe musi mieć tę wartość. W przeciwnym razie wytworzona wartość wyliczenia będzie dowolną wartością wynikającą z konwersji wyrażenia na typ wyliczeniowy. Jeśli VC ++ robi coś innego, to uważam, że jest niezgodny.
bames53
2
co powinien zrobić kompilator zgodny, jeśli enum ma wartości {1,3,5}, a kod próbuje wykonać <cast_cast_tematyczny> od wartości 2. Czym to będzie różnić się od C-cast?
Kirill Kobelev
6
@KirillKobelev Nie używam static_cast, ponieważ robi on coś innego niż rzutowanie w stylu C, używam static_cast, ponieważ rzutowania C ++ są preferowane stylistycznie niż rzutowania C.
bames53
4
@KirillKobelev ”, jeśli wyliczenie ma wartości {1,3,5} " Nie. Typ wyliczenia nie może być ograniczony tylko do tych 3 możliwych wartości: {1,3,5} to wyliczacze (nazwane wartości wyliczeń), a nie same wyliczenia . Jeśli 1,3,5 są możliwymi wartościami wyliczenia , to również 2.
Dobrym pomysłem jest użycie najbardziej ograniczającej obsady i unikanie rzutów w stylu C, aby dać kompilatorowi najlepszą szansę na wykrycie błędów. static_castbyłoby lepiej obsady tutaj.
Mike Seymour
4
@Mike Seymour, problem polega na tym, że w tym przypadku obsada statyczna nie różni się od obsady C-cast. Jak i jaki błąd może wykryć?
Kirill Kobelev
7
@KirillKobelev: Problem polega na tym, że rzutowanie w stylu C nie jest jawne. Może być równy a static_cast, ale równie dobrze może być a const_castnawet gorzej, a reinterpret_castnawet ich kombinacją. Nawet jeśli wiesz teraz, co to ulegnie degradacji, załóżmy, że apóźniej zmienisz na inny typ, równie dobrze może to być rodzaj rzutowania zmian bez otrzymania ostrzeżenia, nie chcesz tego.
KillianDS,
4
@KillianDS „ załóżmy, że później zmienisz na inny typ ”, który to typ?
ciekawy,
2
Tak, te lub ukryta obsada, jeśli jest dostępna. Jest o wiele bardziej jasne, jakie są intencje obsady.
KillianDS,
8
Wydzielając końcowe pytanie: „jak przekonwertować typ na Test::A”, zamiast być sztywnym co do wymogu posiadania obsady , i odpowiadając kilka lat później, wydaje się, że jest to popularne pytanie, o którym nikt inny nie wspomniał o alternatywie , zgodnie ze standardem C ++ 11:
5.2.9 Obsada statyczna
... wyrażenie emoże zostać jawnie przekonwertowane na typ T
przy użyciu static_castformularza, static_cast<T>(e)jeśli deklaracja
T t(e);jest poprawnie uformowana, dla niektórych wynalezionych zmiennych tymczasowych t(8.5). Efekt takiej wyraźnej konwersji jest taki sam, jak wykonanie deklaracji i inicjalizacji, a następnie użycie zmiennej tymczasowej jako wyniku konwersji.
Dlatego bezpośrednie korzystanie z formularza t(e)będzie również działać i możesz go preferować ze względu na porządek:
to rozwiązanie działało w przypadku, gdy opcja kompilatora została zablokowana static_cast <> (kontrola semantyczna). Nie to ma dla mnie sens, ale wciąż jest schludne.
Pan Buisson
1
Test castEnum = static_cast<Test>(a-1);rzuci a na A. Jeśli nie chcesz substrstratu 1, możesz przedefiniować enum:
enumTest{
A:1, B
};
W tym przypadku `Test castEnum = static_cast (a); ' może być użyty do rzutowania A na A.
int a
będzie musiała wynosić 0, ponieważ Test :: A ma domyślną wartość 0, a Test :: B ma domyślną wartość 1. Chyba że fakt rzutowania specjalnie na Test :: A jest poza tym ...Odpowiedzi:
źródło
auto
w tym przypadku? Czy są jakieś ulepszenia wydajności?źródło
Twój kod
Rozwiązanie
źródło
static_cast
byłoby lepiej obsady tutaj.static_cast
, ale równie dobrze może być aconst_cast
nawet gorzej, areinterpret_cast
nawet ich kombinacją. Nawet jeśli wiesz teraz, co to ulegnie degradacji, załóżmy, żea
później zmienisz na inny typ, równie dobrze może to być rodzaj rzutowania zmian bez otrzymania ostrzeżenia, nie chcesz tego.Wydzielając końcowe pytanie: „jak przekonwertować typ na
Test::A
”, zamiast być sztywnym co do wymogu posiadania obsady , i odpowiadając kilka lat później, wydaje się, że jest to popularne pytanie, o którym nikt inny nie wspomniał o alternatywie , zgodnie ze standardem C ++ 11:Dlatego bezpośrednie korzystanie z formularza
t(e)
będzie również działać i możesz go preferować ze względu na porządek:źródło
Test castEnum = static_cast<Test>(a-1);
rzuci a na A. Jeśli nie chcesz substrstratu 1, możesz przedefiniowaćenum
:W tym przypadku `Test castEnum = static_cast (a); ' może być użyty do rzutowania A na A.
źródło