주의 : 공부하면서 정리한 것이기 때문에 오류가 있을 수 있습니다.


실습 과제 4-5 :


다음 함수 템플릿은 std::find 에 대한 "컨테이너 기반" ( 반복자 기반이 아니라 ) 인터페이스를 제공하기 위한 것이다.



현재 코드에서, container_find 는 const 컨테이너들에 대해서는 동작하지 않는다. 코드는 std::find 가 돌려 주는 const_iterator 를 Container::iterator 로 변환하려 하는데, 임의의 컨테이너 형식 x 에 대해 Container 는 const x 가 되기 때문에 컴파일이 실패한다. 이 문제를, container_find 의 반환 형식을 계산하는 작은 메타프로그램을 작성하여 해결하라.




풀이 :


이 코드를 보고 "Container& 인데 왠 const 컨테이너가 들어 온다는 거지?" 라는 의문을 가질 수 있다. 하지만 저건 그냥 type 이 아니라 template 매개 변수라는 것에 주목해야 한다. Container 자체에 예를 들면 const vector< int > 로 선언된 것이 들어 올 수 있다.


일단 에러가 나는 상황을 재현해 보자. 



이 문제를 해결하는 것은 간단하다. 다음과 같은 메타 함수를 하나 만들어서 반환값이 들어갈 부분에 넣어 주면 된다. 의미를 이해하는 것은 크게 어렵지 않을 것이다.



여기에서 특이한 것은 mpl::identity 를 사용한다는 것이다. mpl::eval_if 는 말 그대로 메타 함수를 평가하는 것이기 때문에 mpl::identity 를 사용하지 않으면 그냥 return 값이 make_iterator< Container > 가 되어 버린다. make_iterator 를 메타 함수로서 실행해 주기 위해서는 mpl::identity 를 상속한 형태가 되어야 하며, 최종적으로는 make_iterator< Container >::type 을 실행함으로써  Container::const_iterator 나 Container::iterator 가 반환된다. make_iterator 가 결국은 mpl::identity 를 상속하게 되기 때문에 mpl::identity::type 을 실행한 것과 동일한 효과를 내는 것이다.


이해를 돕기 위해서 mpl::eval_if 가 실행되고 나서의 결과를 단순하게 표현한다면 다음과 같다.



전체 코드는 다음과 같다.





다른 사람의 구현도 살펴 봤는데 필자와 다르지 않았다.


http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?CPPTM_Answers_-_Exercise_4-5


+ Recent posts