Item 4. 추론된 타입을 파악하는 방법을 알아둬라

요즘 IDE들은 컴파일러가 타입을 어떻게 추론했는지 마우스만 갖다 대도 알려준다.

image

하지만 코드가 어느 정도 완성되어 있어야 컴파일러가 코드를 파싱해서 타입 추론을 할 수 있다.

그럼 IDE를 사용하는 방법 이외에 추론된 타입을 확인하는 3가지 방법에 대해 알아보자.


컴파일러의 진단을 이용하는 방법

위 방법은 알고 싶은 타입을 TD(정의 없는 클래스 템플릿)를 통해 인스턴스화 해보는 방법이다.

클래스 템플릿 하나를 정의 없이 선언만 해두고 이를 인스턴스화 하면 인스턴스화 할 템플릿 정의가 없어서 컴파일 오류가 발생한다. 해당 오류 메시지에 우리가 원하는 정보가 들어 있을 수 있다.

//타입을 확인하기 위한 템플릿 클래스.
template <typename T>
class TD;

int main() {
  const int n = 10;
  auto x = n;
  auto y = &n;

  TD<decltype(x)> xType;
  TD<decltype(y)> yType;

  return 0;
}

image


런타임 출력을 이용하는 방법

typeid 연산자를 이용해서 런타임에 특정 오브젝트의 타입을 출력할 수 있다.

const int n = 10;
auto x = n;
auto y = &n;

std::cout << typeid(x).name() << std::endl; // i
std::cout << typeid(y).name() << std::endl; // PKi (PK는 const를 가리키는 pointer를 의미)

하지만 typeid는 reference-ness와 const-ness가 모두 무시된다는 문제가 있다.

int x = 27;
const int cx = x;
const int& rx = x;

std::cout << typeid(x).name() << std::endl;  // int
std::cout << typeid(cx).name() << std::endl; // int
std::cout << typeid(rx).name() << std::endl; // int
template <typename T>
void f(const T& param) {
  std::cout << typeid(T).name() << std::endl;
  std::cout << typeid(param).name() << std::endl;
}

f(4);
// int
// int

typeid를 사용하면 const, volatile이나 &, && 같은 참조 한정사가 모두 무시되어 정확한 타입을 추론하기 어렵다.


Boost.TypeIndex를 이용하는 방법

가장 정확하게 추론된 타입을 확인하는 방법은 boost 라이브러리를 사용하는 것이다.

Boost.TypeIndex를 사용하면 런타임에도 정확한 타입 정보를 얻을 수 있다.

boost::typeindex::type_id_with_cvr은 자신에게 전달된 argument의 const, volatile, 참조 한정사를 모두 보존한 오브젝트의 타입을 출력한다.

#include <boost/type_index.hpp>

using boost::typeindex::type_id_with_cvr;
int x = 27;
const int cx = x;
const int& rx = x;

std::cout << type_id_with_cvr<decltype(x)>().pretty_name() << std::endl;  // int
std::cout << type_id_with_cvr<decltype(cx)>().pretty_name() << std::endl; // const int
std::cout << type_id_with_cvr<decltype(rx)>().pretty_name() << std::endl; // const int&
template <typename T>
void f(const T& param){
  std::cout << type_id_with_cvr<T>().pretty_name() << std::endl;
  std::cout << type_id_with_cvr<decltype(param)>().pretty_name() << std::endl;
}

f(4);
// int
// const int&

추론된 타입을 파악하는 방법을 알아두면 좋지만 타입 추론 규칙을 제대로 이해하는 것이 더욱 중요하다.


카테고리:

업데이트: