본문 바로가기
프로그래밍/C++ 일반

Tip: 변수의 타입 출력하기

by drogrammer 2021. 8. 24.
반응형

C++ 에서는 템플릿, auto 등을 통해 타입추론이 많이 사용되므로 실제 추론된 타입이 무엇인지 궁금할떄가 많다.

아래 스택오버플로우에서 관련 마음에 드는 방법을 찾아서 공유하고자 한다. (C++11 이상 기준)

https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c

 

Is it possible to print a variable's type in standard C++?

For example: int a = 12; cout << typeof(a) << endl; Expected output: int

stackoverflow.com

 

1. 타입 출력 방법

#include <cxxabi.h>
#include <iostream>
#include <memory>

template <class T>
std::string type_name() {
  typedef typename std::remove_reference<T>::type TR;  // Step 1
  std::unique_ptr<char, void (*)(void *)> own(
      abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr,
                          nullptr),  // Step 2
      std::free);
  std::string r = own != nullptr ? own.get() : typeid(TR).name();  // Step 3
  if (std::is_const<TR>::value) r += " const";  // Step 4
  if (std::is_volatile<TR>::value) r += " volatile";  // Step 5
  if (std::is_lvalue_reference<T>::value)  // Step 6
    r += "&";
  else if (std::is_rvalue_reference<T>::value)
    r += "&&";
  return r;
}

위 코드를 간략히 설명하면,

  • Step1. 일단 T 타입으로부터 reference를 제거한 타입을 TR 로 타입 정의를 한 후,
  • Step2. TR의 타입을 알아낸다. 원래 typeid(TR).name() 을 수행하면 타입 ID 가 나오는데, __cxa_demangle을 이용하면 실제 타입 이름을 가져올 수 있다.  예를 들어, int 의 타입 ID 는 'i' 이고, __cxa_demangle 하면 'int' 가 된다.
  • Step3. 최종 리턴할 스트링에 step2 이 성공했으면 demangle 된 타임 이름을 넣고, 실패했으면 타입 ID를 넣는다.
  • Step4. std::is_const<TR> 로 상수 여부 체크 후, 상수면 최종 리턴할 스트링에 ' const' 를 붙인다.
  • Step5. std::is_volatile<TR> 로 volatile 여부 체크 후, 맞으면 최종 리턴할 스트링에 'volatile'을 붙인다.
  • Step6. std::is_lvalue_reference<T>, std::is_rvalue_reference<T> 로 체크 후, 각각 '&', '&&' 를 붙인다.

 

2. 테스트

type_name 함수를 사용하여 아래와 같이 테스트를 해보면,

int main() {
  int a;
  const int b = 0;
  const int &c = 0;
  int &&d = 1;

  std::cout << type_name<decltype(a)>() << std::endl;
  std::cout << type_name<decltype(b)>() << std::endl;
  std::cout << type_name<decltype(c)>() << std::endl;
  std::cout << type_name<decltype(d)>() << std::endl;

  return 0;
}

다음과 같이 출력됨을 볼 수 있다.

int
int const
int const&
int&&
반응형

댓글