티스토리 뷰

 이번 항목에서는 연역된 형식이 무엇인지 궁금할 때, 형식을 알아내는 방법에 대해서 소개한다. 예를 들면 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]);

 위 함수에서 결과는 param 모두 const Widget* 라고 나타난다. param 의 타입이 같은게 말이 되지 않는다. 왜 다른걸까?

그 이유는 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++

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함