본문 바로가기
C++/Effective Modern C++

연역된 형식을 파악하는 방법

by COCO1337 2020. 6. 26.

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: 연역된 형식을 파악하는 방법을 알아두라

반응형

댓글