Sdílet prostřednictvím


Deklarace výčtů v jazyce C++

Výčet je uživatelem definovaný typ tvořený sadou pojmenovaných integrálních konstant nazývaných enumerátory.

[!POZNÁMKA]

Tento článek popisuje typ jazyka C++ podle standardu ISO enum a typ v rozsahu (nebo silný typ) enum class, který je uveden v C++11.Informace o typech public enum class nebo private enum class v C + +/ CLI a C + +/ CX, viz enum class (rozšíření komponent C++).

// unscoped enum:
enum [identifier] [: type]

{enum-list}; 

// scoped enum:
enum [class|struct] 
[identifier] [: type] 
{enum-list};

Parametry

  • identifier
    Název typu daný pro výčet.

  • type
    Základní typ čítačů; všechny čítače mají stejný základní typ.Může být libovolný integrální typ.

  • enum-list
    Čárkami oddělený seznam čítačů ve výčtu.Všechny čítače výčtu nebo názvy proměnných v oboru musí být jedinečné.Mohou však být duplicitní hodnoty.Ve výčtu mimo rozsah je rozsah obklopujícím rozsahem; ve výčtovém rozsahu je enum-list sám.

  • class
    Pomocí tohoto klíčového slova v deklaraci určíte výčtu je obor a identifier musí být poskytnut.Můžete také použít struct klíčové slovo v místě vlastnosti class, jako jsou sémanticky ekvivalentní v tomto kontextu.

Poznámky

Výčet poskytuje kontext k popisu rozsahu hodnot, které jsou reprezentovány jako pojmenované konstanty a které se také nazývají enumerátory.V původních typech výčtů C a C++ jsou nekvalifikované enumerátory viditelné v celém oboru, ve kterém je deklarován výčet.V rámci oboru výčtů musí být název enumerátoru plně kvalifikován názvem typu výčtu.Následující příklad ukazuje tento základní rozdíl mezi dvěma druhy výčtů:

namespace CardGame_Scoped
{
    enum class Suit { Diamonds, Hearts, Clubs, Spades };

    void PlayCard(Suit suit)
    {
        if (suit == Suit::Clubs) // Enumerator must be qualified by enum type
        { /*...*/}
    }
}

namespace CardGame_NonScoped
{
    enum Suit { Diamonds, Hearts, Clubs, Spades };

    void PlayCard(Suit suit)
    {
        if (suit == Clubs) // Enumerator is visible without qualification
        { /*...*/
        }
    }
}

Každému názvu ve výčtu je přiřazena celočíselná hodnota odpovídající jeho umístění v pořadí hodnot ve výčtu.Ve výchozím nastavení je první přiřazená hodnota 0, další je přiřazena 1 a tak dále, ale můžete explicitně nastavit hodnotu čítače, jak je znázorněno zde:

enum Suit { Diamonds = 1, Hearts, Clubs, Spades };

Čítači Diamonds je přiřazena hodnota 1.Následující čítače, pokud jim není uvedena explicitní hodnota, získávají hodnotu z předchozího výčtu navýšenou o jeden.V předchozím příkladu Hearts bude mít hodnotu 2, Clubs bude mít 3, a tak dále.

Každý výčet je považován za konstantu a musí mít jedinečný název v rámci oboru, ve kterém je enum definován (pro výčty bez oboru) nebo v rámci samotného výčtu (pro výčty v oboru).Hodnoty použité pro názvy nemusí být jedinečné.Například pokud deklarace výčtu mimo obor Suit je následující:

enum Suit { Diamonds = 5, Hearts, Clubs = 4, Spades };

Potom jsou hodnoty Diamonds, Hearts, Clubs a Spades 5, 6, 4 a 5 v uvedeném pořadí.Všimněte si, že 5 je použita více než jednou. To je povoleno, i když to nemusí být úmyslné.Tato pravidla jsou stejná pro výčty v oboru.

Pravidla přetypování

Konstanty výčtů bez oboru lze implicitně převádět na int, ale int nelze nikdy implicitně převést na hodnoty výčtu.Následující příklad ukazuje, co se stane, pokud se pokusíte přiřadit hodnotu hand, která není Suit:

int account_num = 135692;
Suit hand;
hand = account_num; // error C2440: '=' : cannot convert from 'int' to 'Suit'

Přetypování vyžaduje převedení hodnoty int na enumerátor v oboru nebo mimo obor.Můžete však povýšit čítač mimo obor na celočíselnou hodnotu bez přetypování.

int account_num = Hearts; //OK if Hearts is in a unscoped enum

Použití implicitních převodů tímto způsobem může způsobit nežádoucí vedlejší účinky.Chcete-li vyloučit programové chyby související s výčtem bez oboru, jsou hodnoty výčtu s oborem psané tučně.Oborový výčty musí být kvalifikován název typu výčtu (identifikátor) a nelze převést implicitně, jak je znázorněno v následujícím příkladu:

namespace ScopedEnumConversions
{
    enum class Suit { Diamonds, Hearts, Clubs, Spades };
 
    void AttemptConversions()
    {
        Suit hand; 
        hand = Clubs; // error C2065: 'Clubs' : undeclared identifier
        hand = Suit::Clubs; //Correct.
        int account_num = 135692;
        hand = account_num; // error C2440: '=' : cannot convert from 'int' to 'Suit'
        hand = static_cast<Suit>(account_num); // OK, but probably a bug!!!

        account_num = Suit::Hearts; // error C2440: '=' : cannot convert from 'Suit' to 'int'
        account_num = static_cast<int>(Suit::Hearts); // OK
}

Všimněte si, že řádek hand = account_num; stále způsobuje chybu, ke které dochází v rámci výčtů bez oboru, jak je uvedeno výše.Je povoleno s explicitním přetypováním.Nicméně s oborem výčtů pokus o převod do dalšího příkazu account_num = Suit::Hearts; již není povolen bez explicitního přetypování.

Viz také

Referenční dokumentace

Deklarace výčtů v jazyce C

Klíčová slova jazyka C++