is_pointer 라는 클래스는 어떻게 작동하나요?
글쓴이: dltkddyd / 작성시간: 목, 2013/11/28 - 12:06오후
is_pointer라는 템플릿 클래스의 정의가 다음과 같던데요.
template<typename _Tp> struct is_pointer : public integral_constant<bool, (__is_pointer_helper<typename remove_cv<_Tp>::type>::value)> { };
상속되는 integral_constant 클래스에서 두 번째 인수는 비타입인수인 것으로 보입니다. 저 value라는 것이 넘어가는 것으로 봐서는요. 그런데 _Tp라는 타입을 보고 __is_pointer_helper라는 클래스에 어떻게 value라는 것이 설정될 수 있나요? 값도 넘겨야 value가 설정될 수 있을 텐데. 잘 이해가 가지 않습니다. 저 __is_pointer_helper라는 클래스의 내부구조를 알 수 있으면 좋을텐데, 알 수가 없네요. 그 이유와 내부구조가 궁금합니다.
Forums:
__is_pointer_helper가 그냥 별건 아니고..
http://en.cppreference.com/w/cpp/types/is_pointer
이 문서에 의하면 굉장히 간단하네요.
std::false_type이랑 true_type은 아마도 그 인테그럴 상수겠지요. 각각 true랑 false일테고..
is_pointer_helper는 두개가 정의되어 있는데, 위의 것은 포인터형이 아니면 false값으로 대체되고, 아래것은 포인터형일 경우 true로 대체됩니다.
세번째줄은 remove_cv를 통해 각종 CV 키워드들(volatile이라든지 const 등등등..)을 제거하고 그 타입을 is_pointer_help에게 먹이는 역할을 하네요.
본문과 제가 인용한 구현법이 서로 달라보이지만 근본적으로는 같은 것입니다. 말하자면 타입이 정해지는 순간 __is_pointer_helper의 리턴값도 그냥 딱 컴파일 타임에 정해지게 됩니다. 그렇기에 따로 값을 넘겨주지 않아도 true나 false가 나올 수 있는 것.
tunecolor님 덕분에 저도 재밌는 것을 많이 알아가게 되네요!
--
무엇보다도 클래스 템플릿의 타입인수를 잘 모르겠는데요.
그러니까 하나는 일반 클래스 템플릿이고 다른 하나는 클래스 템플릿의 특수화 형태로 해서 값을 만든다는 말씀이시죠? 그런데 저는 언급하신 타입인수 class T에서 이해가 잘 안됩니다. 예컨대 이런 것이죠. 아래 코드로 질문 드리겠습니다.
위와 같은 코드가 있는데, main함수 안에서
WhatType나 WhatType이나 모두 template<typename ctarg>에서 ctarg로 받게되면, ctarg 자체가 전자의 경우에는 int이고 후자의 경우에는 int* 가 될 것이고 결국은 두 개의 양식이 서로 충돌되지 않을까요? 그런데 말씀대로 에러는 안 나고 WhatType에서는 앞의 클래스가, WhatType에서는 뒤의 클래스로 value1, value2 객체가 만들어집니다. 포인터의 특수화라는 것이 어떻게 가능한 건가요? 너무 불필요한 질문을 올리는 것인지 모르겠습니다. 그런데 제 머리로는 도대체 이해가 안돼서요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
언급하신 부분은 그냥 받아들이는 편이 좋겠네요.
컴파일러는 컴파일시 특수화된 템플릿의 인수에서 *가 있는 것을 우선적으로 검토한다는 것으로 이해해보도록 하겠습니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
우선적으로 검토한다기보단.
말씀하신 특수화를 사용하되 부분 특수화를 사용한 것입니다.
두번째 라인이 부분 특수화이기 때문에 첫번째 라인 없이는 컴파일조차 되지 않습니다. 포인터 타입일때만 후자가 동작하게 되어 있는 것이죠. 그게 부분 특수화의 역할입니다.
반면 두번째 라인을 지워버리면 항상 false값을 얻게 되겠지요. 또하나 예로..
이딴걸 중간에 집어넣으면 int형일때도 true값을 얻게 될것입니다. 전체 특수화지요. 근데 이 방법을 T의 포인터형에 쓰면.. 그냥 위에 것이 동작해버리므로 제대로 구현을 할 수 없게 됩니다. 위에 써주신 의문대로지요!
--
댓글 달기