내가 C++에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve C++ 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다.  - 최익필

개인적으로 곰곰히 생각해 본다면, Effective C++ 은 "어떠한 경우로 인해서 이러한 결론에 도달했다."를 적어 놓은 책같다. 그래서 이해가 되지 않을 때 마다. "왜 이런 결론이 도달했지??" 라고 생각하면서 곱씹어 읽어 보곤 한다.

항목 46의 주제는 여러번 곱씹어 읽었다. 템플릿이란 생소한(나온지 꽤 되었지만.. 주위에서 쓰는 분들을 못봐서..) 프로그래밍 기법과 문법이 있었기 때문이다. 물론 .. 내용에 대해서는 조금 더 알아두어야 할 것들이 있었다.

정리하자면...
항목 46에서 말하고자 하는 것은 "컴파일러가 템플릿을 컴파일 타입에 인스턴스화(실체화)하기 때문에 런타임에 발생하는 바람직한 타입변환을 쓸수 없다. 만약 템플릿 클래스의 객체를 타입 변환 시키고자 할 때는 비멤버 함수를 클래스 템플릿 안에 정의해 두어야 한다" 이다.


우선 바람직헌 타입 변환이 어떤 코드인지 템플릿이 없이 보여주겠다.

이것이 무엇을 의미하는지는 예전에 정리했던것으로 설명한다. 물론 설명은 링크로..
2008/06/15 항목 24: 타입 변환이 모든 매개변수에 대해 적용되어야 한다면 비멘버 함수를 선언하자

이제 이해가 갔다면, 템플릿을 적용시켜보자. 아마도 이렇게 코드를 짜게 될 것이다.

이렇게 짜게 된다면, 컴파일이 되지 않을 것이다. 그렇다! 이게 이번 항목의 주제이다! 왜!? 왜 에러가 나는 것일까? 곰곰히 생각해 보면, 템플릿은 .. 컴파일 타임에 그 타입을 결정하여, 인스턴스화(코드 생성)을 하게 된다. 그런데 실패 예제를 보게 되면, 29번째 라인, 여기서 "3"만 가지고 클래스 외부 operator*의 템플릿 매개변수 T에 대한 추론을 할수 없게 된다. 그래서 컴파일 타임에 이게 뭐야!? 하면서 컴파일러는 열변을 토한다. 우웩;


그래서 3만 가지고도 그것이 int 타입인것을 알려줄 필요가 있다. 어떻게 알려 주냐하면, 어차피 템플릿이니 클래스 외부 operator*가 템플릿이고 클래스도 템플릿이니 클래스 내부에서 외부 템플릿을 호출할수 있는 구조를 만들어 두면 될듯 싶다.

그렇다면 이렇게 코드를 짜게 될 것이다.

자. 이제 컴파일이 잘 되는 것을 확인 할수 있다. .. 그런데.. 링커는 안되네.. 왜 링커는 안되지!?
다시 템플릿의 인스턴스화가 언제인지 생각해보면, 바로 컴파일 타임이다. 외부 템플릿 함수는 호출 할 수 있으나, 아직 외부 템플릿 함수의 정의가 인스턴스가 되지 않았기 때문에, 컴파일러는 .. 함수 정의가 없는데 함수 호출을 했으니 링커 에러를 토해내게 된다.

그렇다면 정의까지 컴파일 되게 할려면 어떻게 해야 할까? 여기서 한가지 friend 에 대해서 새로운 사실을 알게 될 것이다.


자.. 정상적으로 컴파일 되고, 링크도 되는것을 확인 할수 있을 것이다. 이것은 friend를 이용하여 클래스 내부에 선언 과 정의 하는 기법이다. 이렇게 하면 외부에서 호출되면, 내부의 정의한것으로 처리하게 된다. 이렇게 됨으로써, 어떤 타입이건 받을 수 있게 되어진다.

여담으로 friend 에 대해서 정리해보자.
friend 는
1. 외부 함수 및 클래스를 클래스 내부에 마음것 접근 할수 있도록 내부에서 선언하게 해주는 키워드이다.

여기서 잠깐!
선언이 되니 당연히 정의도 된다. .. 이 기법을 통하여, 템플릿문제를 해결 한 것이다.



이것만은 잊지 말자
1. 모든 매개변수에 대해 암시적 타입 변환을 지원하는 템플릿과 관계 있는 함수를 제공하는 클래스 템플릿을 만들려고 한다면, 이런 함수는 클래스 템플릿 안에 프린드 함수로서 정의하자.

관련링크
http://kelly.springnote.com/pages/601162 <-- 검색하면 나온다.
자료는 더 찾을수 없었음; 3판에서 새롭게 추가된 내용이다.

Effective C++은 감동을 주는 책이다.


  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기