SlideShare a Scribd company logo
1 of 18
Download to read offline
Item 10. 범위 없는 enum 보다
범위 있는 enum을 선호하라
Effective Modern C++ 스터디
이데아 게임즈 손진화
• enum Color { black, white, red }
- C++ 98부터 존재
- 범위 없는(unscoped) enum 이라고 불림
• enum class Color { black, white, red }
- C++ 11 에서 추가됨
- 범위 있는(scoped) enum 이라고 불림
- enum 클래스라고도 불린다
차이점1. 범위
• enum Color { black, white, red }
auto white = false; // error!
• enum class Color { black, white, red }
auto white = false; // ok
Color c = white; // error!
Color c = Color::white; // ok
auto c = Color::white; // ok
차이점1. 범위
=> 범위 있는 enum은 이름공간 (namespace)
의 오염을 줄여주니 적극적으로 사용하도록 하
자
차이점2. 타입 변환
• enum Color { black, white, red }
std::vector<std::size_t> primeFactors
(std::size_t x);
Color c = red;
…
if ( c < 14.5) {
auto factors = primeFactors(c);
…
} // ok
차이점2. 타입 변환
• enum class Color { black, white, red }
std::vector<std::size_t> primeFactors
(std::size_t x);
Color c = red;
…
if ( c < 14.5) {
auto factors = primeFactors(c);
…
} // error!
차이점2. 타입 변환
enum class Color { black, white, red }
…
if ( static_cast<double>(c) < 14.5) {
auto factors = primeFactors(
static_cast<std::size_t>(c));
…
} // ok
차이점2. 타입 변환
=> 범위 있는 enum은 암묵적 타입변환이 되지
않으니 적극적으로 사용하도록 하자
=> 그런데 약간 귀찮긴 하다…
차이점2. 타입 변환
using UserInfo = std::tuple<std::string,
std::string,
std::size_t>;
UserInfo uInfo;
…
auto val = std::get<1>(uInfo);
차이점2. 타입 변환
enum UserInfoFields {uiName,
uiEmail,
uiReputation};
auto val = std::get<uiEmail>(uInfo);
// ok
차이점2. 타입 변환
enum class UserInfoFields {uiName,
uiEmail,
uiReputation};
auto val = std::get<
static_cast<std::size_t>(uiEmail)>(uInfo);
// ok
=> 템플릿 함수로 변환하려면?
차이점2. 타입 변환
template<typename E>
constexpr typename std::underlying_type<E>::type
toUType(E enumerator) noexcept
{
return
static_cast<typename
std::underlying_type<E>::type>(enumerator);
}
차이점2. 타입 변환
template<typename E>
constexpr std::underlying_type_t<E>
toUType(E enumerator) noexcept
{
return
static_cast<
std::underlying_type_t<E>>(enumerator);
}
// C++ 14
차이점2. 타입 변환
template<typename E>
constexpr auto
toUType(E enumerator) noexcept
{
return
static_cast<
std::underlying_type_t<E>>(enumerator);
}
auto val = std::get<
toUtype(UserInfoField::uiEmail)>(uInfo);
// ok, C++ 14
차이점3. 전방 선언(forward declaration)
바탕 형식 (underlying type) 이란 열거형 상수
가 프로그램 안에서 실제로 저장되는 정수 형식
을 말합니다.
표준에 따르면 열거형의 바탕 형식은 구현(즉
컴파일러)이 결정합니다.
열거형에서 가장 큰 상수를 담기에 충분한 크기
의 정수 형식이기만 하면 어떤 것이라도 상관이
없습니다.
enum Color { black, white, red };
-> 바탕형식 : char
enum Status { …
indeterminate = 0xffffffff};
-> 바탕형식 : char 이상의 정수형
차이점3. 전방 선언(forward declaration)
• 범위 없는 enum
- 정의에 따라 컴파일 시 타입이 결정됨
- 정의가 바뀌면 컴파일 다시 해야 함
- 전방 선언 허용하지 않음
enum Color; // error!
enum Status: std::uint32_t; // ok (C++ 11)
차이점3. 전방 선언(forward declaration)
• 범위 있는 enum
- 기본 바탕형식은 int로 정해져 있다
- 전방 선언 허용
- 정의가 바뀌어도 컴파일 안 해도 됨
enum class Status; // ok, 바탕형식 int
enum class Status: std::uint32_t; // ok
차이점3. 전방 선언(forward declaration)

More Related Content

More from 진화 손

C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf진화 손
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf진화 손
 
C++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templatesC++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templates진화 손
 
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...진화 손
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions진화 손
 
C++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdfC++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdf진화 손
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types진화 손
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements진화 손
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library진화 손
 
C++20 Coroutine
C++20 CoroutineC++20 Coroutine
C++20 Coroutine진화 손
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules진화 손
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules진화 손
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)진화 손
 
C++20 std::map::contains
C++20 std::map::containsC++20 std::map::contains
C++20 std::map::contains진화 손
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers진화 손
 
C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]진화 손
 
C++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contextsC++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contexts진화 손
 
C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>진화 손
 
C++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptrC++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptr진화 손
 
C++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fieldsC++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fields진화 손
 

More from 진화 손 (20)

C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf
 
C++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templatesC++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templates
 
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions
 
C++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdfC++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdf
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library
 
C++20 Coroutine
C++20 CoroutineC++20 Coroutine
C++20 Coroutine
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)
 
C++20 std::map::contains
C++20 std::map::containsC++20 std::map::contains
C++20 std::map::contains
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers
 
C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]
 
C++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contextsC++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contexts
 
C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>
 
C++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptrC++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptr
 
C++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fieldsC++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fields
 

Effective Modern C++ item 10

  • 1. Item 10. 범위 없는 enum 보다 범위 있는 enum을 선호하라 Effective Modern C++ 스터디 이데아 게임즈 손진화
  • 2. • enum Color { black, white, red } - C++ 98부터 존재 - 범위 없는(unscoped) enum 이라고 불림 • enum class Color { black, white, red } - C++ 11 에서 추가됨 - 범위 있는(scoped) enum 이라고 불림 - enum 클래스라고도 불린다
  • 3. 차이점1. 범위 • enum Color { black, white, red } auto white = false; // error! • enum class Color { black, white, red } auto white = false; // ok Color c = white; // error! Color c = Color::white; // ok auto c = Color::white; // ok
  • 4. 차이점1. 범위 => 범위 있는 enum은 이름공간 (namespace) 의 오염을 줄여주니 적극적으로 사용하도록 하 자
  • 5. 차이점2. 타입 변환 • enum Color { black, white, red } std::vector<std::size_t> primeFactors (std::size_t x); Color c = red; … if ( c < 14.5) { auto factors = primeFactors(c); … } // ok
  • 6. 차이점2. 타입 변환 • enum class Color { black, white, red } std::vector<std::size_t> primeFactors (std::size_t x); Color c = red; … if ( c < 14.5) { auto factors = primeFactors(c); … } // error!
  • 7. 차이점2. 타입 변환 enum class Color { black, white, red } … if ( static_cast<double>(c) < 14.5) { auto factors = primeFactors( static_cast<std::size_t>(c)); … } // ok
  • 8. 차이점2. 타입 변환 => 범위 있는 enum은 암묵적 타입변환이 되지 않으니 적극적으로 사용하도록 하자 => 그런데 약간 귀찮긴 하다…
  • 9. 차이점2. 타입 변환 using UserInfo = std::tuple<std::string, std::string, std::size_t>; UserInfo uInfo; … auto val = std::get<1>(uInfo);
  • 10. 차이점2. 타입 변환 enum UserInfoFields {uiName, uiEmail, uiReputation}; auto val = std::get<uiEmail>(uInfo); // ok
  • 11. 차이점2. 타입 변환 enum class UserInfoFields {uiName, uiEmail, uiReputation}; auto val = std::get< static_cast<std::size_t>(uiEmail)>(uInfo); // ok => 템플릿 함수로 변환하려면?
  • 12. 차이점2. 타입 변환 template<typename E> constexpr typename std::underlying_type<E>::type toUType(E enumerator) noexcept { return static_cast<typename std::underlying_type<E>::type>(enumerator); }
  • 13. 차이점2. 타입 변환 template<typename E> constexpr std::underlying_type_t<E> toUType(E enumerator) noexcept { return static_cast< std::underlying_type_t<E>>(enumerator); } // C++ 14
  • 14. 차이점2. 타입 변환 template<typename E> constexpr auto toUType(E enumerator) noexcept { return static_cast< std::underlying_type_t<E>>(enumerator); } auto val = std::get< toUtype(UserInfoField::uiEmail)>(uInfo); // ok, C++ 14
  • 15. 차이점3. 전방 선언(forward declaration) 바탕 형식 (underlying type) 이란 열거형 상수 가 프로그램 안에서 실제로 저장되는 정수 형식 을 말합니다. 표준에 따르면 열거형의 바탕 형식은 구현(즉 컴파일러)이 결정합니다. 열거형에서 가장 큰 상수를 담기에 충분한 크기 의 정수 형식이기만 하면 어떤 것이라도 상관이 없습니다.
  • 16. enum Color { black, white, red }; -> 바탕형식 : char enum Status { … indeterminate = 0xffffffff}; -> 바탕형식 : char 이상의 정수형 차이점3. 전방 선언(forward declaration)
  • 17. • 범위 없는 enum - 정의에 따라 컴파일 시 타입이 결정됨 - 정의가 바뀌면 컴파일 다시 해야 함 - 전방 선언 허용하지 않음 enum Color; // error! enum Status: std::uint32_t; // ok (C++ 11) 차이점3. 전방 선언(forward declaration)
  • 18. • 범위 있는 enum - 기본 바탕형식은 int로 정해져 있다 - 전방 선언 허용 - 정의가 바뀌어도 컴파일 안 해도 됨 enum class Status; // ok, 바탕형식 int enum class Status: std::uint32_t; // ok 차이점3. 전방 선언(forward declaration)