일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- c++
- effective modern c++
- virtual function
- Effective c++
- 영화
- 암시적 변환
- 언리얼
- Smart Pointer
- 상속
- operator new
- 반복자
- 예외
- implicit conversion
- UE4
- reference
- 티스토리챌린지
- effective stl
- resource management class
- 스마트 포인터
- more effective c++
- 메타테이블
- 참조자
- 게임
- lua
- 비교 함수 객체
- 영화 리뷰
- 다형성
- 오블완
- exception
- 함수 객체
Archives
- Today
- Total
스토리텔링 개발자
[Effective Modern C++] 4. 추론 타입 파악하기 본문
728x90
항목 4. 추론된 타입을 파악하는 방법을 알아두라
추론 타입 확인 방법 세 가지
- 코드를 작성, 수정하는 시점(IDE 편집기)
- 컴파일 시점(컴파일 에러를 통한 확인)
- 런타임 시점(코드 삽입을 통한 타입 정보 출력)
IDE 편집기
- 프로그램 개체(변수, 매개변수, 함수 등) 위에 마우스 커서를 올리면 그 개체의 타입을 표시해 주는 것이 많다.
- IDE 안에서 C++ 컴파일러(혹은 컴파일러의 front가) 실행되기 때문에 가능한 것.
- 그러므로 코드가 컴파일 될 수 있는 상태여야 한다.
- 복잡한 타입의 경우 그리 도움이 되지 않을 수 있다.
컴파일러 에러 메시지
- 일부러 문제를 발생시킨다면, 에러 메시지에는 그 문제를 일으킨 타입이 언급된다.
// TD를 선언만 해둔다. TD는 "Type Dispalyer(형식 표시기)"를 뜻한다.
template<typename T>
class TD;
// 아래처럼 하면, 각각의 타입이 에러로 출력된다.
TD<decltype(x)> xType;
TD<decltype(y)> yType;
실행시점 출력
- printf를 이용한다.
- 까다로운 점은, 원하는 타입으로부터 표시에 적합한 형태의 텍스트를 만들어 내는 것이다.
- typeid와 std::type_info::name을 사용하면 될까?
std::cout << typeid(x).name() << '\n';
std::cout << typeid(y).name() << '\n';
- 위 코드가 하고 있는 가정
- 각 객체가 typeid를 적용하면 std::type_info 타입의 객체가 산출되고,
- 그 std::type_info 객체에는 name이라는 멤버 함수가 있으며,
- 그 멤버 함수는 타입의 이름을 나타내는 C 스타일 문자열(const char*)일 것이다.
- 표준에 따르면 std::type_info::name이 의미 있는 뭔가를 돌려준다는 보장이 없다.
- 하지만 대체로 컴파일러들은 개발자에게 도움을 주려고 노력한다.
- 문제 1. std::type_info::name이 출력하는 정보의 표현 방법이 일관성이 없다.
- 문제 2. std::type_info::name은 믿을만하지 않다.
template<typename T>
void f(const T& param)
{
using std::cout;
cout << "T = " << typeid[T].name() << '\n';
cout << "param = " << typeid[param].name() << '\n';
}
std::vector<Widget> createVec();
const auto vw = createVec();
if(!vw.empty())
{
f(&vw[0]);
...
}
// GNU 컴파일러
// PK는 Pointer to Konst(const)를 뜻한다.
// T = PK6Widget(즉, const Widget*를 뜻한다)
// param = PK6Widget
// MS 컴파일러
// T = class Widget const *
// param = class Widget const *
- T와 param의 타입이 같다?
- param의 선언된 타입은 const T& 이므로
- param의 타입은 const Widget * const& 여야 한다.
- 하지만 틀린 타입을 출력한다.
- 이는 std::type_info::name은 반드시 주어진 타입을 템플릿 함수에 값 전달 매개변수로 전달된 것처럼 취급해야 한다는 표준을 준수했기 때문이다.
- 그래서 param의 타입에서 참조 제거, 상수성 제거(항목 1 참조)가 되어 const Widget*이 된 것이다.
- 마찬가지로 IDE 편집기가 표시하는 타입 정보 역시 불확실한 경우가 많다.
Boost TypeIndex 라이브러리(Boost.TypeIndex)
- 이는 반드시 성공하게 설계되어 있다.
- 표준은 아니지만, IDE나 TD 같은 템플릿도 표준이 아닌 건 똑같다.
#include <boost/type_index.hpp>
template<typename T>
void f(const T& param)
{
using std::cout;
using boost:typeindex::type_id_with_cvr;
// T를 표시
cout << "T = "
<< type_id_with_cvr<T>().pretty_name()
<< '\n';
// param의 타입을 표시
cout << "param = "
<< type_id_with_cvr<decltype(param)>().pretty_name()
<< '\n';
}
728x90
'개발 > Effective Modern C++' 카테고리의 다른 글
[Effective Modern C++] 5. 타입 명시보다 auto (0) | 2025.02.11 |
---|---|
[Effective Modern C++] 3. decltype (0) | 2025.02.07 |
[Effective Modern C++] 2. auto 타입 추론 규칙 (0) | 2025.02.06 |
[Effective Modern C++] 1. 템플릿 타입 추론 규칙 (0) | 2025.02.05 |
Comments