#include <iostream>
struct a {
enum LOCAL_A { A1, A2 };
};
enum class b { B1, B2 };
int foo(int input) { return input; }
int main(void) {
std::cout << foo(a::A1) << std::endl;
std::cout << foo(static_cast<int>(b::B2)) << std::endl;
}
To a::LOCAL_A
jest to, co próbuje osiągnąć silnie typowane wyliczenie, ale jest mała różnica: normalne wyliczenia można przekonwertować na typ całkowity, podczas gdy silnie typowane wyliczenia nie mogą tego zrobić bez rzutowania.
Czy jest więc sposób na przekonwertowanie wartości wyliczenia o jednoznacznie określonym typie na typ całkowity bez rzutowania? Jeśli tak, w jaki sposób?
źródło
Jak powiedzieli inni, nie można mieć niejawnej konwersji, a to jest zamierzone.
Jeśli chcesz, możesz uniknąć konieczności określania typu podstawowego w rzutowaniu.
źródło
Wersja C ++ 14 odpowiedzi udzielonej przez R.Martinho Fernandes byłaby:
Podobnie jak w przypadku poprzedniej odpowiedzi, zadziała to z każdym rodzajem wyliczenia i typem bazowym. Dodałem
noexcept
słowo kluczowe, ponieważ nigdy nie zgłosi wyjątku.Aktualizacja
Pojawia się również w Effective Modern C ++ autorstwa Scotta Meyersa . Zobacz punkt 10 (jest szczegółowo opisany na ostatnich stronach pozycji w moim egzemplarzu książki).
źródło
źródło
Nie. Nie ma naturalnego sposobu .
W rzeczywistości jedną z motywacji stojących za silnym typowaniem
enum class
w C ++ 11 jest zapobieganie ich cichej konwersji doint
.źródło
W innych odpowiedziach podano przyczynę braku niejawnej konwersji (z założenia).
Osobiście używam jednoargumentowego
operator+
do konwersji z klas wyliczeniowych do ich bazowego typu:Co daje dość niewielkie „narzuty związane z pisaniem”:
Gdzie faktycznie używam makra do tworzenia wyliczeń i funkcji operatora w jednym ujęciu.
źródło
Mam nadzieję, że to pomoże tobie lub komuś innemu
źródło
un.i
jest to „aktywny element członkowski” i można odczytać tylko aktywnego członka unii.static_cast
.Krótka odpowiedź brzmi: nie możesz, jak wskazują powyższe posty. Ale w moim przypadku po prostu nie chciałem zaśmiecać przestrzeni nazw, ale nadal mieć niejawne konwersje, więc po prostu zrobiłem:
Sortowanie przestrzeni nazw dodaje warstwę bezpieczeństwa typu, podczas gdy nie muszę statycznie rzutować żadnych wartości wyliczeniowych na typ bazowy.
źródło
Foo::Foo
. Dostęp do elementów członkowskich można uzyskać jakoFoo::bar
iFoo::baz
można je niejawnie rzutować (a więc nie ma dużego bezpieczeństwa typu). Prawdopodobnie lepiej jest prawie zawsze używać klas wyliczeniowych, zwłaszcza jeśli rozpoczynasz nowy projekt.Wydaje się to niemożliwe w przypadku tubylców
enum class
, ale prawdopodobnie można kpićenum class
zclass
:W tym przypadku,
byłoby równoważne z:
W większości jest to odpowiednik oryginału
enum class
. Możesz bezpośrednio wrócićb::B1
for w funkcji z typem zwracanymb
. Możeszswitch case
z tym zrobić itp.W duchu tego przykładu możesz użyć szablonów (prawdopodobnie razem z innymi rzeczami) do uogólnienia i mockowania dowolnego możliwego obiektu zdefiniowanego przez
enum class
składnię.źródło
Jak wielu powiedziało, nie ma sposobu na automatyczną konwersję bez dodawania narzutów i zbyt dużej złożoności, ale możesz trochę zmniejszyć pisanie i sprawić, by wyglądało lepiej, używając lambd, jeśli niektóre rzutowanie będą używane trochę w scenariuszu. Dodałoby to trochę wywołania narzutu funkcji, ale uczyniłoby kod bardziej czytelnym w porównaniu z długimi ciągami static_cast, jak widać poniżej. Może to nie być przydatne w całym projekcie, ale tylko w klasie.
źródło
Komisja C ++ zrobiła jeden krok naprzód (określanie zakresu wyliczeń z globalnej przestrzeni nazw) i pięćdziesiąt kroków wstecz (brak zaniku typu wyliczenia na liczbę całkowitą). Niestety
enum class
po prostu nie nadaje się do użytku, jeśli potrzebujesz wartości wyliczenia w jakikolwiek nie symboliczny sposób.Najlepszym rozwiązaniem jest nieużywanie go w ogóle, a zamiast tego samodzielne określanie zakresu wyliczenia przy użyciu przestrzeni nazw lub struktury. W tym celu są wymienne. Będziesz musiał wpisać trochę więcej, odwołując się do samego typu wyliczenia, ale prawdopodobnie nie będzie to często.
źródło