일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- lua
- operator new
- 참조자
- 상속
- resource management class
- 암시적 변환
- reference
- 비교 함수 객체
- 예외
- Smart Pointer
- 게임
- exception
- implicit conversion
- 언리얼
- more effective c++
- 오블완
- 반복자
- 함수 객체
- 티스토리챌린지
- effective modern c++
- Effective c++
- virtual function
- 메타테이블
- effective stl
- 영화
- 영화 리뷰
- c++
- UE4
- 스마트 포인터
- iterator
Archives
- Today
- Total
스토리텔링 개발자
[Effective Modern C++] 9. typedef vs using 본문
Effective C++/Effective Modern C++
[Effective Modern C++] 9. typedef vs using
김디트 2025. 2. 17. 10:54728x90
항목 9. typedef보다 별칭 선언을 선호하라
typedef와 using
typedef std::unique_ptr<std::unordered_map<std::string, std::string>> UPtrMapSS;
- C++11에서도 물론 동작하지만
- C++11에서는 별칭 선언(alias declaration)도 제공한다.
using UPtrMapSS = std::unique_ptr<std::unordered_map<std::string, std::string>>;
- 하는 일이 완전히 동일한데, 왜 별칭 선언을 선호해야 할까?
함수 포인터
typedef void (*FP)(int, const std::string&);
using FP = void (*)(int, const std::string&);
- 별칭 선언 쪽의 가독성이 낫다.
템플릿
- 별칭 템플릿(alias templates)
- typedef는 템플릿화 할 수 없지만, 별칭 선언은 템플릿화 할 수 있다.
- C++98에서는 템플릿화된 struct 안에 내포된 typedef들을 활용하는 편법을 동원해야 했지만,
- C++11에서는 좀 더 직접적으로 표현할 수 있게 되었다.
// using 버전
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>
MyAllocList<Widget> lw;
// typedef 버전
template<typename T>
struct MyAllocList
{
typedef std::list<T, MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw;
- typedef 버전을 템플릿 안에서 사용하려고 하면
-
template<typename T> class Widget { private: typename MyAllocList<T>::type list; // typename으로 // MyAllocList<T>::type은 템플릿 타입 매개변수에 의존적인 타입이라는 걸 명시한다. ... };
- typedef 앞에 typename을 붙여야 한다.
- C++은 의존 타입 이름 앞에는 반드시 typename을 붙여야 한다는 규칙이 있다.
- 그리고, MyAllocList<T>::type은 의존 타입(dependent type)이다.
- 템플릿 특수화로 인해 MyAllocList<T>::type이 타입 이외의 것을 지칭할 가능성이 있기 때문이다.(EC++ 항목 42 참조)
-
- using 버전에서는 불필요하다.
-
template<typename T> class Widget { private: MyAllocList<T> list; ... };
- 여전히 템플릿 매개변수 T에 의존하는 것처럼 보이지만, 컴파일러는 그렇게 생각하지 않는다.
- 컴파일러가 Widget 템플릿을 처리하는 과정에서 MyAllocList<T>가 쓰인 부분에 도달했을 때,
- 컴파일러는 그 MyAllocList<T>가 타입의 이름임을 이미 알고 있다.
- MyAllocList가 타입 템플릿이므로, MyAllocList<T>는 반드시 타입 이름이어야 하기 때문이다.
- 즉, MyAllocList<T>는 비의존 타입(non-dependent type)이다.
-
템플릿 메타 프로그래밍(template metaprogramming)과 타입 특성정보(type trait)
- 템플릿 타입 매개변수를 적당히 가공하여 다른 타입을 만들어내야 하는 경우가 있다.
- T에 붙은 const를 제거한다거나,
- T에 참조자(&)를 붙여준다거나.
- C++11은 이런 종류의 변환을 수행할 수 있는 타입 특성정보(type trait)를 제공한다.
- <type_traits> 헤더 안에 있는 템플릿들이 그것이다.
std::remove_const<T>::type // const T를 T로 변환
std::remove_reference<T>::type // T&나 T&&를 T로 변환
std::add_lvalue_reference<T>::type // T를 T&로 변환
- 헌데, 이 타입 특성정보들은 using이 아니라 typedef의 용법으로 구현되어 있다!
- C++14에는 별칭 템플릿 버전들이 포함되었다.
// const T를 T로 변환
std::remove_const<T>::type C++11 버전
std::remove_const_t<T> // C++14 버전
// T&나 T&&를 T로 변환
std::remove_reference<T>::type C++11 버전
std::remove_reference_t<T> // C++14 버전
// T를 T&로 변환
std::add_lvalue_reference<T>::type // C++11 버전
std::add_lvalue_reference_t<T> // C++14 버전
- 만일 C++11 버전을 사용해야 하더라도, 14 버전으로 변경해서 사용하기는 너무나 쉽다.
template<class T>
using remove_const_t = typename remove_const<T>::type;
template<class T>
using remove_reference_t = typename remove_reference<T>::type;
template<class T>
using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
728x90
'Effective C++ > Effective Modern C++' 카테고리의 다른 글
[Effective Modern C++] 11. 삭제된 함수(deleted function) (0) | 2025.02.19 |
---|---|
[Effective Modern C++] 10. enum class (0) | 2025.02.18 |
[Effective Modern C++] 8. nullptr (0) | 2025.02.14 |
[Effective Modern C++] 7. 괄호 초기화 vs 중괄호 초기화 (0) | 2025.02.13 |
[Effective Modern C++] 6. auto의 타입 추론 실패 (0) | 2025.02.12 |
Comments