IDE 편집기
일반적으로 간단한 형식의 경우에는 IDE가 알려준 정보가 쓸만하다.
컴파일러의 진단 메시지
컴파일러가 연역한 형식을 파악할 때 원하는 형식 때문에 컴파일에 문제가 발생하게 만드는 것이다.
const int theAnswer = 42;
auto x = theAnswer;
auto y = &theAnswer;
template<typename T>
class TD;
TD<decltype(x)> xType;
TD<decltype(y)> yType;
컴파일러마다 형태는 다르지만 동일한 정보를 제공하게 된다.
실행시점 출력
std::cout << typeid(x).name() << '\n';
std::cout << typeid(y).name() << '\n';
연역된 형식들을 typeid를 사용해 출력한다.
이 접근 방식은, x나 y 같은 객체에 대해 typeid를 적용하면 std::type_info 형식의 객체가 산출되며 그 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';
}
이러한 경우 T와 param 둘다 형식이 class Widget const*가 된다. 하지만 템플릿 f에서 param의 선언된 형식은 const T&이다. 즉 T와 param 형식이 같아지게 되는데 std::type_info::name이 반드시 주어진 형식을 템플릿 함수에 값 전달 매개변수로서 전달된 것처럼 취급해야 하기 때문에 벌어진 현상이다.
std::type_info::name과 IDE가 실패하더라도 Boost.TypeIndex 라이브러리가 도움이 될 수 있다.
std::vector<Widget> createVec();
const auto vw = createVec();
if (!vw.empty()) {
f(&vw[0]);
}
typeid를 사용했을때는 잘못된 형식 정보를 산출했었다.
Boost.TypeIndex에서는 T의 경우 class Widget const*를, param의 경우 class Widget const * const &를 출력해낸다.
Conclusion
- 컴파일러가 연역하는 형식을 IDE편집기나 컴파일러 오류메시지, Boost TypeIndex라이브러리를 이용하여 파악할 수 있는 경우가 많다.
- 일부 도구의 결과는 유용하지도 않고 정확하지도 않을 수 있으므로, C++의 형식 연역 규칙들을 제대로 이해하는 것이 필요하다.
Reference
Effective Modern C++ 항목 4: 연역된 형식을 파악하는 방법을 알아두라
'C++ > Effective Modern C++' 카테고리의 다른 글
auto가 원치 않은 형식으로 연역될 때에는 명시적 형식의 초기치를 사용 (0) | 2020.06.28 |
---|---|
명시적 형식 선언보다는 auto를 선호하라 (0) | 2020.06.27 |
decltype의 작동 방식 (0) | 2020.06.26 |
auto 형식 연역 규칙 (0) | 2020.06.24 |
템플릿 형식 연역 규칙 (0) | 2020.06.23 |
댓글