Szukaj…
Podstawowa deklaracja wyliczenia
Standardowe wyliczenia pozwalają użytkownikom zadeklarować użyteczną nazwę dla zestawu liczb całkowitych. Nazwy są łącznie nazywane licznikami. Wyliczenie i powiązane z nim elementy wyliczające są zdefiniowane w następujący sposób:
enum myEnum
{
enumName1,
enumName2,
};
Wyliczenie to typ , który różni się od wszystkich innych typów. W tym przypadku nazwa tego typu to myEnum
. Oczekuje się, że obiekty tego typu przyjmą wartość modułu wyliczającego w ramach wyliczenia.
Elementy wyliczające zadeklarowane w ramach wyliczenia są stałymi wartościami typu wyliczenia. Chociaż wyliczacze są zadeklarowane w ramach typu, operator zasięgu ::
nie jest potrzebny do uzyskania dostępu do nazwy. Tak więc nazwa pierwszego modułu wyliczającego to enumName1
.
Operator zakresu można opcjonalnie wykorzystać do uzyskania dostępu do modułu wyliczającego w ramach wyliczenia. Tak więc enumName1
można również przeliterować myEnum::enumName1
.
Modułom obliczającym są przypisywane wartości całkowite zaczynające się od 0 i wzrastające o 1 dla każdego modułu wyliczającego w wyliczeniu. W powyższym przypadku enumName1
ma wartość 0, a enumName2
ma wartość 1.
Użytkownikowi można również przypisać określoną wartość do liczników; ta wartość musi być integralnym stałym wyrażeniem. Wyliczacze, których wartości nie są wyraźnie podane, będą mieli wartość ustawioną na wartość poprzedniego wyliczacza + 1.
enum myEnum
{
enumName1 = 1, // value will be 1
enumName2 = 2, // value will be 2
enumName3, // value will be 3, previous value + 1
enumName4 = 7, // value will be 7
enumName5, // value will be 8
enumName6 = 5, // value will be 5, legal to go backwards
enumName7 = 3, // value will be 3, legal to reuse numbers
enumName8 = enumName4 + 2, // value will be 9, legal to take prior enums and adjust them
};
Wyliczenie w instrukcjach switch
Częstym zastosowaniem enumeratorów są instrukcje przełączników, dlatego często pojawiają się w automatach stanów. W rzeczywistości użyteczną cechą instrukcji switch z wyliczeniami jest to, że jeśli nie zostanie dołączona żadna instrukcja domyślna dla przełącznika i nie zostaną użyte wszystkie wartości wyliczenia, kompilator wyda ostrzeżenie.
enum State {
start,
middle,
end
};
...
switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]
Iteracja przez wyliczenie
Nie ma wbudowanego mechanizmu iteracji po wyliczeniu.
Ale jest kilka sposobów
dla
enum
tylko z kolejnymi wartościami:enum E { Begin, E1 = Begin, E2, // .. En, End }; for (E e = E::Begin; e != E::End; ++e) { // Do job with e }
z enum class
operator ++
musi zostać zaimplementowany:
E& operator ++ (E& e)
{
if (e == E::End) {
throw std::out_of_range("for E& operator ++ (E&)");
}
e = E(static_cast<std::underlying_type<E>::type>(e) + 1);
return e;
}
używając kontenera jako
std::vector
enum E { E1 = 4, E2 = 8, // .. En }; std::vector<E> build_all_E() { const E all[] = {E1, E2, /*..*/ En}; return std::vector<E>(all, all + sizeof(all) / sizeof(E)); } std::vector<E> all_E = build_all_E();
i wtedy
for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) { E e = *it; // Do job with e; }
lub
std::initializer_list
i prostsza składnia:enum E { E1 = 4, E2 = 8, // .. En }; constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
i wtedy
for (auto e : all_E) { // Do job with e }
Wyliczenia z zakresu
C ++ 11 wprowadza tak zwane wyliczenia zakresowe . Są to wyliczenia, których członkowie muszą być kwalifikowani przy pomocy enumname::membername
. Wyliczenia zakresowe są deklarowane przy użyciu składni enum class
. Na przykład, aby zapisać kolory w tęczy:
enum class rainbow {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};
Aby uzyskać dostęp do określonego koloru:
rainbow r = rainbow::INDIGO;
enum class
nie można domyślnie konwertować na int
bez rzutowania. Więc int x = rainbow::RED
jest niepoprawny.
Wyliczenia zakresowe pozwalają również określić typ bazowy , który jest typem używanym do reprezentowania członka. Domyślnie jest to int
. W grze Kółko i krzyżyk możesz przechowywać element jako
enum class piece : char {
EMPTY = '\0',
X = 'X',
O = 'O',
};
Jak możesz zauważyć, enum
mogą mieć przecinek końcowy po ostatnim elemencie.
Deklaracja przekazania w trybie enum w C ++ 11
Wyliczenia o zasięgu:
...
enum class Status; // Forward declaration
Status doWork(); // Use the forward declaration
...
enum class Status { Invalid, Success, Fail };
Status doWork() // Full declaration required for implementation
{
return Status::Success;
}
Nieokreślone wyliczenia:
...
enum Status: int; // Forward declaration, explicit type required
Status doWork(); // Use the forward declaration
...
enum Status: int{ Invalid=0, Success, Fail }; // Must match forward declare type
static_assert( Success == 1 );
Szczegółowy przykład wielu plików można znaleźć tutaj: Przykład sprzedawcy ślepych owoców