티스토리 뷰
[Effective Modern C++] 항목 4. 연역된 형식을 파악하는 방법을 알아두라
pppgod 2019. 9. 2. 21:19이번 항목에서는 연역된 형식이 무엇인지 궁금할 때, 형식을 알아내는 방법에 대해서 소개한다. 예를 들면 auto를 사용하는 경우인데 이를 알아내기란 쉽지가 않다. 이 책에서는 형식을 알아낼 수 있는 3가지 방법을 소개했다.
- IDE 편집기
- 컨파일러의 진단 메시지
- 실행시점 출력
IDE 편집기
좋은 IDE를 사용하고 있다면 현재 연역된 형식이 무엇인지 알려준다. 일반적으로 타입에 마우스를 올려두기만 하면된다. 그러나 복잡한 형식에서는 IDE가 알려주지 못할 수도 있다.
컨파일러의 진단 메시지
decltype 과 template 을 이용해서 컨파일러 에러를 통해 알아내는 방법이다. 방법은 다음과 같다.
template<typename T>
class TD;
TD<decltype(x)> xType; // 컴파일 에러
TD<decltype(y)> yType; // 컴파일 에러
xType과 yType을 선언한 부분에서 컴파일 에러가 나타나며 x와 y의 타입이 무엇인지 알려줄 것이다.
실행시점 출력
typeid와 std::type_info::name
이 방법은 로그를 이용해서 확인하는 방법이다. 먼저 typeid와 std::type_info::name 을 사용하는 방법이 있다.
cout << typeid(x).name() << endl;
그러나 여기에 문제가 하나 있다.
template<typename T>
void f(const T& param)
{
cout << typeid(T).name() << endl;
cout << typeid(param).name() << endl;
}
std::vector<Widget> createVec();
const auto vw = createVec();
f(&vw[0]);
위 함수에서 결과는 T 와 param 모두 const Widget* 라고 나타난다. param 과 T 의 타입이 같은게 말이 되지 않는다. 왜 다른걸까?
그 이유는 param 의 형식을 일부러 틀리기 때문이다. 표준에 따르면 std::type_info::name 은 값 전달 매개변수로 취급해야하기 때문이다. 실제 param 의 형식은 const Widget * const& 인데 값 전달이기 때문에 뒤에 나타난 const 와 참조가 사라지게 되는 것이다.
boost 라이브러리의 typeindex
보다 정확한 형식을 알아내는 방법은 바로 typeindex를 사용하는 것이다.
template<typename T>
void f(const T& param)
{
cout << type_id_with_cvr<T>().pretty_name() << endl;
cout << type_id_with_cvr<decltype(param)>().pretty_name() << endl;
}
type_id_with_cvr 함수에서 cvr이 붙은 이유가 바로 const 와 volatile, reference (참조성)을 유지하기 때문이다.
참고 서적
스콧 마이어스, Effective Modern C++
'C++ > Effective Modern C++' 카테고리의 다른 글
[Effective Modern C++] 항목 6. auto가 원치 않은 형식으로 연역될 때에는 명시적 형식의 초기치를 사용하라 (0) | 2019.09.08 |
---|---|
[Effective Modern C++] 항목 5. 명시적 형식 선언보다는 auto를 선호하라 (0) | 2019.09.08 |
[Effective Modern C++] 항목 3. decltype의 작동 방식을 숙지하라 (0) | 2019.09.02 |
[Effective Modern C++] 항목 2. auto의 형식 연역 규칙을 숙지하라 (0) | 2019.08.25 |
[Effective Modern C++] 항목 1. 템플릿 형식 연역 규칙을 숙지하라 (1) | 2019.08.25 |
- Total
- Today
- Yesterday
- forward
- Unreal
- auto
- Effective Modern C++
- std::forward
- 발아시기
- C++14
- 다이소
- Future
- const
- Effective
- C++11
- std::move
- detach
- MOVE
- C
- 보편참조
- 포인터
- Override
- Modern
- Overloading
- 람다
- Forwarding
- async
- thread
- Join
- CPP
- Perfect
- 보편 참조
- C++
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |