#stl copy_if 알고리즘 구현
STL 알고리즘 이름의 _if 접미사는 술어 함수(predicate)를 인자로 받는 것을 의미한다. 이 술어 함수를 알고리즘 안에서 호출해서 돌려받은 반환 값에 따라 동작을 수행할지 말지를 결정하게 된다. 예를 들면 count_if()는 술어 함수 호출결과가 true인 원소들의 개수를 세는 알고리즘이고 remove_if()는 술어 함수 호출 결과가 true인 원소들을 제거하는 알고리즘이다.
시퀀스(Sequences - vector, list, deque) 알고리즘 중에 _if 가 있을만한 알고리즘인데 없는 알고리즘이 있다. 가장 단순한 형태인 복사를 수행하는 copy() 알고리즘이 주인공인데, 정말 있을법한데 없는 알고리즘이다. Effective STL 항목 36에서 이 사실을 알게 됐는데, 혹시나 싶어서 TC++PL을 보니 이 책에도 copy_if()
에 대한 언급이 있었다. 표준 위원회가 STL 명세를 결정할 때 제거한 알고리즘이다. Where is copy_if (was: STL question: where is find_first_not_of?)에서 비야네 스트롭스트룹의 답변을 볼 수 있다.
copy_if 구현
template<class In, class Out, class Pred>
Out copy_if(In first, In last, Out res, Pred p)
{
while (first != last) {
if (p(*first)) *res++ = *first;
++first;
}
return res;
}
이렇게 TC++PL에 실린 것처럼 직접 구현할 수도 있고
template<class In, class Out, class Pred>
Out copy_if(In first, In last, Out res, Pred p)
{
return std::remove_copy_if(first, last, res, not1(p));
}
remove_copy_if() 알고리즘과 not1() 단항 술어 함수 어댑터를 사용해서 구현할 수 있다. VS 2005에 딩컴웨어 STL이나 STLport 같이 많이 사용하는 STL 구현 코드에서는 디버그 옵션을 켜면 반복자(iterator) 범위 체크 등 여러 검사를 해주는데, 그런 안정장치들을 직접 삽입해 줄 게 아니면 위처럼 직접 구현하는 것보다 구현된 알고리즘과 어댑터를 사용해 구현하는 게 안정성이나 재활용 측면에서 낫다고 생각한다.
copy() 알고리즘 활용
std::copy(
v.begin(),
v.end(),
std::ostream_iterator<int>(std::cout, " "));
참고로 copy()
는 시작과 끝을 가리키는 반복자를 인자로 받는 시퀀스 생성자가 있어서 시퀀스에서 시퀀스로 단순 복사용으로는 잘 쓰이지 않는데, 세 번째 인자로 출력 반복자를 받는 것을 이용하면 시퀀스 원소들을 콘솔에 출력하는 작업 같은 일을 간단하게 처리할 수 있다.
PS : TC++PL을 정독하지 않고 필요한 부분만 참고 하고 있는데, Effective STL 정리가 마무리되면 다른 C++ 책들은 미루고 TC++PL을 정독해야겠다. 모든 게 다 이 책 안에 있다.
참고
- TC++PL
- Effective STL 항목 36