스토리텔링 개발자

[Effective STL] 36. copy_if 본문

개발/Effective STL

[Effective STL] 36. copy_if

김디트 2024. 12. 26. 10:52
728x90

항목 36. copy_if를 적절히 구현해 사용하자

 

 

 

copy 알고리즘
  • 모던 C++ 이전에는 아래와 같은 copy 알고리즘들만이 있었다.
    1. copy
    2. copy_backward
    3. replace_copy
    4. reverse_copy
    5. replace_copy_if
    6. unique_copy
    7. remove_copy
    8. rotate_copy
    9. remove_copy_if
    10. partial_sort_copy
    11. uninitialized_copy
  • 즉, copy_if가 없어서 구현해야 했다.
  • 어떤 식으로 구현해서 사용했었는지 재미로나마 알아보자.

 

 

copy_if가 필요한 상황
bool isDefective(const Widget& w); // Widget이 문제가 있는지 알려주는 함수

vector<Widget> widgets;
...
// c++11 이전에는 이게 안됐다..
copy_if(widgets.begin(), widgets.end(), ostream_iterator<Widget>(cerr, "\n"), isDefective);

 

 

 

 

copy_if를 '대충' 만들기
template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if(InputIterator begin, InputIterator end, OutputIterator destBegin, Predicate p)
{
    // 술어 구문(Predicate)이 참이 아닌 데이터를 제외하고 모두 복사해라.. 라는 아이디어.
    return remove_copy_if(begin, end, destBegin, not1(p));
}

// 하지만 컴파일 에러가 발생한다.
copy_if(widgets.begin(), widgets.end(), ostream_iterator<Widget>(cerr, "\n"), isDefective);
  • 원인은 isDefective에 not1을 적용할 수 없기 때문이다.(항목 41 참조)
    • not1은 함수 포인터에 바로 적용할 수 없다.
    • 우선 ptr_fun에 넘기고 적용해야 한다.

 

 

 

copy_if를 '제대로 대충' 만들기
template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if(InputIterator begin, InputIterator end, OutputIterator destBegin, Predicate p)
{
    while(begin != end)
    {
        if(p(*begin)) // 조건을 만족하면
        	*destBegin++ = *begin; // begin을 destBegin에 넣고, destBegin의 다음 위치로 이동
        ++begin; // 다음 begin 체크
    }
    
    return destBegin;
}

 

728x90
Comments