Sök…
Grundläggande uppräkning av uppräkning
Standarduppräkningar tillåter användare att förklara ett användbart namn för en uppsättning heltal. Namnen kallas kollektivt som uppräknare. En uppräkning och dess tillhörande räknare definieras enligt följande:
enum myEnum
{
enumName1,
enumName2,
};
En uppräkning är en typ , en som skiljer sig från alla andra typer. I detta fall är namnet på denna typ myEnum
. Objekt av denna typ förväntas anta värdet på en räknare inom uppräkningen.
De uppräknare som anges inom uppräkningen är konstanta värden av typen av uppräkningen. Även om uppräknare deklareras inom typen, behövs inte omfattningsoperatören ::
för att få åtkomst till namnet. Så namnet på den första enumName1
är enumName1
.
Omfångsoperatören kan valfritt användas för att komma åt en uppräknare inom en uppräkning. Så enumName1
kan också stavas myEnum::enumName1
.
Uppräknare tilldelas heltal med början från 0 och ökar med 1 för varje teller i en uppräkning. Så i ovanstående fall har enumName1
värdet 0, medan enumName2
har värdet 1.
Enumeratorer kan också tilldelas ett specifikt värde av användaren; detta värde måste vara ett integrerat konstant uttryck. Räknare som inte har uttryckligen tillhandahållit värden kommer att ha sitt värde inställt på värdet på föregående teller + 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
};
Uppräkning i switch-uttalanden
En vanlig användning för räknare är för switch-uttalanden och så de ofta visas i tillståndsmaskiner. I själva verket är en användbar funktion för switch-uttalanden med uppräkningar att om inget standarduttalande ingår för omkopplaren, och inte alla värden på enum har använts, kommer kompilatorn att ge en varning.
enum State {
start,
middle,
end
};
...
switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]
Iteration över enum
Det finns inget inbyggt för att iterera över uppräkning.
Men det finns flera sätt
för
enum
med endast på varandra följande värden:enum E { Begin, E1 = Begin, E2, // .. En, End }; for (E e = E::Begin; e != E::End; ++e) { // Do job with e }
med enum class
operator ++
implementeras:
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;
}
använder en behållare som
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();
och då
for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) { E e = *it; // Do job with e; }
eller
std::initializer_list
och en enklare syntax:enum E { E1 = 4, E2 = 8, // .. En }; constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
och då
for (auto e : all_E) { // Do job with e }
Scoped enums
C ++ 11 introducerar så kallade scoped-enums . Detta är uppräkningar vars medlemmar måste vara kvalificerade med enumname::membername
. Omfattade enums deklareras med enum class
syntax. För att till exempel lagra färgerna i en regnbåge:
enum class rainbow {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};
Så här får du åtkomst till en specifik färg:
rainbow r = rainbow::INDIGO;
enum class
es kan inte implicit konverteras till int
utan rollspel. Så int x = rainbow::RED
är ogiltig.
Omfattade enums tillåter dig också att ange den underliggande typen , som är den typ som används för att representera en medlem. Som standard är det int
. I ett Tic-Tac-Toe-spel kan du lagra stycket som
enum class piece : char {
EMPTY = '\0',
X = 'X',
O = 'O',
};
Som du kanske märker, kan enum
ha en efterföljande komma efter den sista medlemmen.
Enum framåtdeklaration i C ++ 11
Omfattade uppräkningar:
...
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;
}
Obeskrivna uppräkningar:
...
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 );
Ett fördjupat exempel på flera filer kan hittas här: Exempel på handlare av blind frukt