Zoeken…
Basis opsomming
Met standaardtellingen kunnen gebruikers een nuttige naam opgeven voor een reeks gehele getallen. De namen worden gezamenlijk aangeduid als opsommers. Een opsomming en de bijbehorende opsommers zijn als volgt gedefinieerd:
enum myEnum
{
enumName1,
enumName2,
};
Een opsomming is een type dat verschilt van alle andere typen. In dit geval is de naam van dit type myEnum
. Van dit soort objecten wordt verwacht dat ze de waarde van een teller binnen de opsomming aannemen.
De opsommers die binnen de opsomming zijn opgegeven, zijn constante waarden van het type opsomming. Hoewel de opsommers binnen het type worden gedeclareerd, is de scope-operator ::
niet nodig om toegang te krijgen tot de naam. Dus de naam van de eerste teller is enumName1
.
De scope-operator kan optioneel worden gebruikt om toegang te krijgen tot een teller in een opsomming. Dus enumName1
kan ook worden gespeld als myEnum::enumName1
.
Tellers krijgen hele waarden toegewezen die beginnen bij 0 en oplopen met 1 voor elke teller in een opsomming. Dus in het bovenstaande geval heeft enumName1
de waarde 0, en enumName2
heeft de waarde 1.
Tellers kunnen ook een specifieke waarde krijgen van de gebruiker; deze waarde moet een integrale constante uitdrukking zijn. Tellers waarvan de waarden niet expliciet worden opgegeven, moeten hun waarde instellen op de waarde van de vorige 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
};
Opsomming in schakeluitspraken
Een veelgebruikt gebruik voor tellers is voor schakelinstructies en ze verschijnen daarom meestal in statusmachines. Een handig kenmerk van schakelinstructies met opsommingen is dat als er geen standaardinstructie voor de schakeloptie is opgenomen en niet alle waarden van het opsommingsteken zijn gebruikt, de compiler een waarschuwing geeft.
enum State {
start,
middle,
end
};
...
switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]
Iteratie over een opsomming
Er is geen ingebouwd om over opsomming te herhalen.
Maar er zijn verschillende manieren
voor
enum
met alleen opeenvolgende waarden:enum E { Begin, E1 = Begin, E2, // .. En, End }; for (E e = E::Begin; e != E::End; ++e) { // Do job with e }
met enum class
moet operator ++
worden geïmplementeerd:
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;
}
een container gebruiken als
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();
en toen
for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) { E e = *it; // Do job with e; }
of
std::initializer_list
en een eenvoudigere syntaxis:enum E { E1 = 4, E2 = 8, // .. En }; constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
en toen
for (auto e : all_E) { // Do job with e }
Scoped enums
C ++ 11 introduceert wat bekend staat als scoped enums . Dit zijn opsommingen waarvan de leden moeten zijn gekwalificeerd met enumname::membername
. Scoped-enums worden gedeclareerd met behulp van de syntaxis van de enum class
. Om bijvoorbeeld de kleuren in een regenboog op te slaan:
enum class rainbow {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};
Toegang krijgen tot een specifieke kleur:
rainbow r = rainbow::INDIGO;
enum class
kunnen niet impliciet worden omgezet in int
zonder cast. Dus int x = rainbow::RED
is ongeldig.
Met Scoped-enums kunt u ook het onderliggende type opgeven, het type dat wordt gebruikt om een lid te vertegenwoordigen. Standaard is dit int
. In een Tic-Tac-Toe-spel kun je het stuk opslaan als
enum class piece : char {
EMPTY = '\0',
X = 'X',
O = 'O',
};
Zoals je misschien ziet, kan enum
s een komma achter het laatste lid hebben.
Enum forward-verklaring in C ++ 11
Scoped-opsommingen:
...
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;
}
Unscoped-opsommingen:
...
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 );
Een uitgebreid voorbeeld van meerdere bestanden vindt u hier: Voorbeeld van een blinde fruithandelaar