9.14 Unscoped enumerations

주홍영·2022년 3월 14일
0

Learncpp.com

목록 보기
105/199

https://www.learncpp.com/cpp-tutorial/unscoped-enumerations/

Enumeration

An enumeration (also called an enumerated type or an enum) is a compound data type where every possible value is defined as a symbolic constant (called an enumerator).

symbolic constant를 사용할 수 있도록 해주는 enum type
예를 들어 색에 대한 정보를 저장하고 싶을 때 red = 1, blue = 2이런식으로
해서 숫자로 판별하는 것보다, 직접 red나 blue로 instantiate 할 수 있게끔 도와줄 수 있다

Unscoped enumerations

unscoped enum 은 enum 키워드로 정의할 수 있다

// Define a new unscoped enumeration named Color
enum Color
{
    // Here are the enumerators
    // These symbolic constants define all the possible values this type can hold
    // Each enumerator is separated by a comma, not a semicolon
    red,
    green,
    blue, // trailing comma optional but recommended
}; // the enum definition must end with a semicolon

int main()
{
    // Define a few variables of enumerated type Color
    Color apple { red };   // my apple is red
    Color shirt { green }; // my shirt is green
    Color cup { blue };    // my cup is blue

    Color socks { white }; // error: white is not an enumerator of Color
    Color hat { 2 };       // error: 2 is not an enumerator of Color

    return 0;
}

Enumerated types are distinct types

enum type은 typedef 나 using을 이용한 alias 처럼 별칭을 다는게 아닌
distinct(별개의) type으로 써 c++에서 취급된다
아래 예시를 보자

enum Pet
{
    cat,
    dog,
    pig,
    whale,
};

enum Color
{
    black,
    red,
    blue,
};

int main()
{
    Pet myPet { black }; // compile error: black is not an enumerator of Pet
    Color shirt { pig }; // compile error: pig is not an enumerator of Color

    return 0;
}

즉 별개의 타입으로 취급하기 때믄에 Pet에 Color 타입을 집어 넣으면 compile error가 발생한다

The scope of unscoped enumerations

enum의 scope는 정의된 scope에 따라 결정된다

enum Color
{
    red, // 참고로 red 는 0이다
    green,
    blue, // blue is put into the global namespace
};

enum Feeling
{
    happy,
    tired,
    blue, // error: naming collision with the above blue
};

int main()
{
    Color apple { red }; // my apple is red
    Feeling me { happy }; // I'm happy right now (even though my program doesn't compile)

    return 0;
}

위 코드에서 Color와 Feeling 모두 global scope에 정의가 되어 있다
따라서 Color의 blue와 Felling의 blue가 naming collision을 일으킨다
따라서 compile error가 발생하게 되는 것이다

이러한 conflict를 막기위해 자체적으로 unscoped enum은 named scope region을 지원한다
따라서 Color::red와 같은 접근이 가능하다

Avoiding enumerator naming collisions

이러한 collision을 피하기 위한 여러 방법이 있다

enum Color
{
    color_red,
    color_blue,
    color_green,
};

enum Feeling
{
    feeling_happy,
    feeling_tired,
    feeling_blue, // no longer has a naming collision with color_blue
};

int main()
{
    Color paint { color_blue };
    Feeling me { feeling_blue };

    return 0;
}

위의 코드에서는 variable 이름에 type이름을 붙이면서 구분을 하는 것이다
하지만 여전히 좋은 방법은 아니다
다음의 방법은 아까보다 더욱 깔끔한 방법이다

namespace color
{
    // The names Color, red, blue, and green are defined inside namespace color
    enum Color
    {
        red,
        green,
        blue,
    };
}

namespace feeling
{
    enum Feeling
    {
        happy,
        tired,
        blue, // feeling::blue doesn't collide with color::blue
    };
}

int main()
{
    color::Color paint { color::blue };
    feeling::Feeling me { feeling::blue };

    return 0;
}

namespace를 이용하여 prefix로 구분할 수 있도록 되었기 때문에
collision을 미연에 방지한다

profile
청룡동거주민

0개의 댓글