1부에선 기본적인 개념을 정리했습니다. 2부에서는 BOOST_FOREACH를 보다 확장해서 사용하거나, 최적화 해서 사용 하는 방법에 대해서 알아 봅니다.


BOOST_FOREACH 의 확장

BOOST_FOREACH 를 사용하다보면, 내가 정의한 새로운 타입의 집합체도 BOOST_FOREACH를 이용하여 훑고 싶을 때가 있습니다. 어떻게 하면 사용 할 수 있을까요? 여기서 말하는 확장은 바로 "새로운 타입을 BOOST_FOREACH"로 돌리기 위한 확장 입니다.

확장을 하는 방법으로 다음 코드를 보세요.
여기선 예로 std::string 이라고 정하는데, 원리는 똑같습니다.

BOOST_FOREACH가 Boost.Range 기반으로 만들어 졌기 때문에, Boost.Ragne 중 ragne_begin 과 end, 그리고 const 형태만 오버로드 해주면 됩니다. .. 개인적으로 이 방법을 추천하지는 않습니다. 왜냐하면 boost 네임스페이스까지 추가해야 되기 때문입니다.(추가 하는거야 상관 없겠지만, 안건들이고도 할 수 있다면 더 좋을 것입니다)

추가로 추천하지 않는 이유가 있는데, ... 어렵습니다. 신경쓸껏도 많고, .. 보다 정확하게 할려면 Boost.Ragne를 또 봐야 할지 모릅니다.

이번 확장은 여기까지 정리하고, 뒤에 가서 이것을 커버할 수 있는 방법을 소개 하겠습니다.


복사할 수 없는 순차 타입을 BOOST_FOREACH 로 돌리기

여기서 한가지 짚고 넘어가야 하는게 있는데, BOOST_FOREACH 를 사용 할 때, 콜렉션 타입, 즉, 훑일 녀석이 복사된 임시객체로 이용 될 수 있습니다. BOOST_FOREACH를 다 분석한게 아니기 때문에 메뉴얼에 의존적인 설명밖에 못하겠네요. 

그렇다고 이게 꼭 복사된 임시객체만을 이용한다는 것을 의미하지는 않는다고 합니다. 자세한건 메뉴얼을 보셔야 될것 같습네요.


이렇게 하면 복사를 사용하지 않고 BOOST_FOREACH 를 쓰라고 하는것 입니다. 하지만 boost에 새로 룰을 추가하는 것이 조금 씁쓸합니다.


가벼운 프록시 순차 타입에 대한 BOOST_FOREACH 최적화 하기

안타깝게도 모든 컴파일러가 BOOST_FOREACH 에 대해서 동일한 코드를 생성하는게 아닙니다. 그래서 그런지 몇몇 컴파일러에선 특정 BOOST_FOREACH 가 잘 작동하게 하기 위해서 다소 느린 코드가 생성된다고 합니다.

그럴 때, 최적화 하기 위하여, 다음의 코드를 사용 한다고 합니다.

하지만 이 방법도 추천하지 않습니다. proxy로 부르겠다고 상속하고, 룰 추가 하는건, 익숙치 않을 뿐더러, 서로 의존적인 부분이 상당히 많습니다.


위에서 모든 말한 3가지 조건을 만족할 수 있는 방법 제시

바로 Boost.Range 에 있는, iterator_range or sub_range 를 생성하여, BOOST_FOREACH 에 사용 하면 됩니다. 자, 한가지 예를 보여 드리겠습니다.


이 방법은 다음의 장점을 갖습니다.

  1. 새로운 타입의 컬렉션(컨테이너 등)이 있다면, 인터페이스를 추가하기 보다 Range의 유틸리티를 사용하여, BOOST_FOREACH 로 돌릴수 있습니다.
  2. 복사되지 않은 컬렉션의 경우도 잘 작동할 수 있도록 도와 줍니다.
  3. BOOST_FOREACH 사용시 컬렉션의 복사(컨테이너 등)가 발생 할 경우, 전체복사가 아닌, 컬렉션의 양 끝(2개) iterator만 복사만 이루어 집니다.
  4. 훑기의 범위를 정할 수 있습니다.

단점은 다음과 같습니다.

  1. 새로운 컬렉션의 경우 iterator 를 뽑을 수 있어야 합니다.
  2. 핸드 코드가 조금 추가 될 수 있습니다.
  3. iterator 무효화 개념을 모른 상태로 코드를 짜다보면, 자칫 위험해 질 수 있습니다.(크래쉬!)

마지막으로 더 봐야할 문서를 하나 더 링크합니다. 이 문서는 boost 공식 메뉴얼이며, BOOST_FOREACH 사용시 유의해야 하는 상황을 말하고 있습니다.

http://www.boost.org/doc/libs/1_40_0/doc/html/foreach/pitfalls.html

그럼 전 이만...

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