반응형
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&&
반응형
댓글