Effective C++/Effective STL
[Effective STL] 36. copy_if
김디트
2024. 12. 26. 10:52
728x90
항목 36. copy_if를 적절히 구현해 사용하자
copy 알고리즘
- 모던 C++ 이전에는 아래와 같은 copy 알고리즘들만이 있었다.
- copy
- copy_backward
- replace_copy
- reverse_copy
- replace_copy_if
- unique_copy
- remove_copy
- rotate_copy
- remove_copy_if
- partial_sort_copy
- 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