C++ magic_enum, enum 이름을 문자열로 얻는 방법
C++ enum은 표준으로 이름을 문자열로 못 바꾸고, C++ magic_enum은 컴파일 타임 매크로/템플릿으로 이름과 값을 연결합니다. 따라서 enum_name과 enum_cast를 사용하면 enum 값의 이름 조회와 문자열·정수에서 enum으로 되돌리는 작업을 다룰 수 있지만, 컴파일러와 값 범위 조건은 확인해야 합니다.
이 글은 Neargye/magic_enum 공식 README와 문서를 2026-08-26 기준으로 정리한 일반 설명이며, 컴파일러와 enum 값 범위, 플래그 설정에 따라 동작은 달라질 수 있습니다.
C++에서 enum 이름을 문자열로 못 바꾸는 이유는?
한 줄 답: C++의 표준 enum에는 선언에 적은 enumerator 식별자를 문자열로 돌려주는 표준 라이브러리 API가 없습니다.
enum은 이름이 붙은 상수인 enumerator를 가지는 별도 타입이며, 저장과 변환의 기반에는 정수형인 underlying type이 있습니다. std::underlying_type이나 std::to_underlying은 값을 정수로 다루는 기능이지, 선언에 사용한 이름을 복원하는 기능은 아닙니다.
따라서 Color::RED를 출력할 때 표준 기능만으로 "RED"라는 식별자 문자열이 자동으로 나오지 않습니다. cppreference의 열거형 출력 예제처럼 이름을 직접 내보내려면 switch와 operator<< 같은 매핑 코드를 작성해야 합니다.
magic_enum은 무엇을 해주나?
한 줄 답: 이 라이브러리는 C++17 헤더 전용 방식으로 매크로나 별도 매핑표 없이 enum의 이름 조회, 문자열·정수 역변환, 값 순회를 컴파일 타임 중심으로 제공합니다.
magic_enum은 enum을 문자열로 바꾸는 조회, 문자열이나 정수에서 enum을 찾는 역변환, enum 값 목록을 순회하는 기능을 한 헤더에서 제공합니다. 공식 README는 이를 별도 매크로나 보일러플레이트 코드 없이 사용하는 enum 정적 리플렉션으로 설명합니다.
#include <magic_enum/magic_enum.hpp>
핵심 API는 enum_name, enum_cast, enum_values, enum_count입니다. 헤더를 복사하거나 CMake와 패키지 관리 도구를 통해 통합할 수 있으며, MIT License로 배포됩니다.
enum_name과 enum_cast는 어떻게 쓰나?
한 줄 답: enum_name은 값의 이름을 string_view로 돌려주고, enum_cast는 문자열 또는 정수를 optional<enum>으로 안전하게 변환합니다.
공식 Color 예시는 RED = -10, BLUE = 0, GREEN = 10을 사용하며, 호출 형태는 다음과 같습니다. enum_name은 값에서 이름을 찾고 enum_cast는 문자열 또는 정수에서 enum 값을 찾습니다.
enum class Color { RED = -10, BLUE = 0, GREEN = 10 };
auto name = magic_enum::enum_name(Color::RED);
auto from_name = magic_enum::enum_cast<Color>("GREEN");
auto from_value = magic_enum::enum_cast<Color>(0);
enum_name(Color::RED)는 string_view로 "RED"를 반환합니다. 이름이 없는 값이나 반사 범위를 벗어난 값에서는 빈 문자열을 반환합니다.
컴파일 타임 값으로 호출하는 enum_name<value>()는 이름 없는 값에서 컴파일 오류가 발생합니다. 이 형태는 값 인자를 받는 버전보다 컴파일이 빠르고 enum_range 제한을 받지 않으므로, 두 호출 형태의 범위와 실패 방식을 구분해야 합니다.
문자열 "GREEN" 또는 정수 0을 enum_cast<Color>에 넘기면 결과는 optional<Color>입니다. 일치 항목이 없으면 빈 optional이 되며, has_value()를 확인하거나 value_or(Color::RED)로 기본값을 정할 수 있고, case_insensitive를 사용하면 ASCII 대소문자 무시 매칭을 선택할 수 있습니다.
enum_values<Color>()는 값 기준으로 정렬된 배열을 반환합니다. 이 Color 예시의 순서는 RED, BLUE, GREEN이며, enum_count<Color>()의 결과는 3입니다.
직접 switch 짜는 것과 무엇이 다른가?
한 줄 답: 직접 switch는 값과 문자열의 매핑을 따로 유지하지만, 이 라이브러리는 반사 범위 안의 선언을 기준으로 이름·값 목록·개수를 함께 제공합니다.
직접 switch와 operator<<를 작성하면 각 enumerator에 대응하는 case와 문자열을 함께 관리해야 합니다. enum에 항목을 추가하거나 삭제할 때 이 병렬 매핑의 수정이 빠지면 출력 이름이 누락되거나 예상한 처리가 되지 않을 수 있습니다.
반면 이 라이브러리는 컴파일러 함수 시그니처에서 얻은 정보를 이용해 반사 범위 안의 이름을 찾습니다. 범위 안에 새 enumerator를 추가하면 enum_name, enum_values, enum_count가 선언을 기준으로 함께 갱신되어 별도 case 목록을 만들 필요가 줄어듭니다.
이는 표준 enum reflection이 아니라 컴파일러별 함수 시그니처 문자열을 활용하는 구현입니다. 직접 switch보다 빠르거나 바이너리 비용이 없다고 단정할 근거는 공식 문서에 없으므로, 유지해야 할 매핑 코드와 프로젝트 제약을 기준으로 선택해야 합니다.
C++ 기술면접 질문 10가지는 enum 이름 변환 API가 아니라 C++ 개념을 점검하는 관련 글입니다.
magic_enum의 한계는 무엇인가?
한 줄 답: 기본 반사 범위와 컴파일러별 구현 의존성, flags·별칭·전방 선언 조건을 확인하지 않으면 이름이나 값이 기대와 다르게 처리될 수 있습니다.
일반 enum의 기본 반사 범위는 [-128, 127]입니다. 범위를 넓히려면 MAGIC_ENUM_RANGE_MIN·MAGIC_ENUM_RANGE_MAX를 조정하거나 타입별 customize::enum_range<E>를 특수화해야 하며, 타입별 (max - min)은 UINT16_MAX보다 작아야 합니다.
값이 희소하고 넓은 구간에 흩어져 있으면 범위 확장에 따른 constexpr 평가 부담을 프로젝트에서 확인해야 합니다. 반사 대상은 전방 선언된 enum이 될 수 없고, 같은 값을 공유하는 alias enumerator는 컴파일러에 따라 구분이 달라질 수 있습니다.
이 구현은 __PRETTY_FUNCTION__ 또는 __FUNCSIG__ 같은 컴파일러별 함수 시그니처에 의존합니다. constexpr 평가 단계 제한, Visual Studio IntelliSense 문제, 특히 Clang에서 템플릿 안 enum이 올바르게 동작하지 않을 수 있다는 제한도 공식 문서에 있습니다.
flags는 일반 enum과 별도 의미로 처리해야 하며, customize::enum_range<E>::is_flags = true를 설정하고 enum_flags_name·enum_flags_cast를 사용합니다. flags 반사는 MAGIC_ENUM_RANGE_MIN·MAGIC_ENUM_RANGE_MAX로 제어되지 않고 값 0은 반사되지 않습니다.
임베디드/실무에서 언제 쓰면 되나?
한 줄 답: 지원되는 C++17 도구체인에서 로그·직렬화·디버그 문자열처럼 enum 이름이 필요한 경우에 검토하되, 값 범위와 빌드 제약은 대상 프로젝트에서 확인해야 합니다.
README의 헤더 전용 컴파일러 호환 하한은 Clang/LLVM 5 이상, MSVC++ 15.3 이상 또는 Visual Studio 2017 이상, Xcode 10 이상, GCC 9 이상입니다. 지원 확인용 MAGIC_ENUM_SUPPORTED 매크로도 제공됩니다.
헤더 전용이고 C++17을 대상으로 하므로, 이 조건을 만족하면서 기본 범위 안의 enum이나 타입별 범위를 명시할 수 있는 enum에 적합합니다. 로그·직렬화·디버그 문자열처럼 선언 이름을 반복해서 매핑해야 하는 경로에서 매핑 코드의 양을 줄이는 용도로 검토할 수 있습니다.
반대로 MCU 도구체인이 GCC 9보다 오래되었거나, 값이 기본 [-128, 127]에서 멀리 떨어진 희소 enum이면 먼저 호환성과 범위 특수화를 확인해야 합니다. 바이너리 크기와 컴파일 시간이 엄격한 프로젝트는 공식 문서에 공통 수치가 제시되지 않았으므로 대상 설정으로 확인해야 합니다.
이 글은 C++17 헤더 전용 경로를 다루며, C++26 리플렉션 사용법이나 컴파일러 지원 표는 다루지 않습니다.
FAQ
한 줄 답: 값 범위, 실패 처리, flags 여부, alias와 전방 선언, 컴파일러 지원 여부를 각각 확인해야 합니다.
다음 질문은 공식 README와 문서에 나온 동작 조건을 짧게 정리한 것입니다. 조회 결과가 비어 있는 경우를 확인 가능한 변환 실패로 처리하는 것이 핵심입니다.
| 질문 | 답변 |
|---|---|
이름 없는 값에 enum_name을 호출하면 어떻게 됩니까? | 값 인자를 받는 버전은 빈 string_view를 반환합니다. 컴파일 타임 enum_name<value>()는 이름 없는 값에서 컴파일 오류가 발생합니다. |
| 문자열이 enum에 없으면 어떻게 처리합니까? | enum_cast의 has_value()를 확인하거나 value_or(Color::RED)로 기본값을 정합니다. |
| 비트 flags도 같은 API로 처리합니까? | is_flags = true를 설정한 뒤 enum_flags_name·enum_flags_cast를 사용합니다. flags에서는 값 0이 반사되지 않습니다. |
| alias나 전방 선언 enum도 반사됩니까? | 전방 선언된 enum은 반사할 수 없습니다. alias enumerator 구분은 컴파일러에 따라 달라질 수 있습니다. |
| 지원 여부는 어떻게 확인합니까? | README의 컴파일러 하한과 MAGIC_ENUM_SUPPORTED 매크로를 확인합니다. |
출처
한 줄 답: enum의 표준 동작은 cppreference, 라이브러리 API·제약·지원 조건은 공식 저장소와 문서에서 확인할 수 있습니다.
저장소와 README는 헤더 전용 구조, 공식 Color 예시, 컴파일러 호환 조건을 확인하는 자료입니다. reference.md와 limitations.md는 API, enum_range, flags, alias와 constexpr 관련 제한을 확인하는 자료이며, cppreference는 표준 enum과 직접 작성하는 출력 예제를 확인하는 자료입니다.