안녕하세요. 방수철입니다.
이번 글에서는 copy_if, copy_n, find_if_not에 대해서 알아보도록 하겠습니다.

copy_if

MSDN에 등록된 copy_if에 대한 선언은 다음과 같습니다.

template<class InputIterator, class OutputIterator, class BinaryPredicate>
    OutputIterator copy_if(
        InputIterator_First, 
        InputIterator _Last,
        BinaryPredicate _Comp
    );

copy_if는 _First 가 가리키는 위치부터 _Last가 가리키는 위치까지 _Comp조건을 만족하는 element를 copy하게 됩니다.
그런데 뭔가 허전하죠? 이 선언에는 copy를 수행해서 저장될 container가 빠져있습니다. 아마 MSDN의 오류인 것 같습니다.
copy인 만큼 당연히 source가 되는 container에는 변화가 없습니다.

VC2010에 포함된 헤더파일에 있는 선언은 다음과 같습니다.

template<class _InIt,
	class _OutIt,
	class _Pr> inline
	_OutIt copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
		_Pr _Pred)

_Dest 인자가 선언되어 있는 것을 확인할 수 있습니다.

아래 코드는 20의 약수를 골라내는 프로그램입니다.

	const int N=12;
	list<int> src;
	list<int> dest;
	// 데이터 초기화
	for(int i=1 ; i<=N ; i++)
		src.push_back(i);
 
	// 약수만을 복사
	copy_if(src.begin(), src.end(), back_inserter(dest), [=](int n){ return N % n == 0; });
 
	// 결과 출력
	cout<<N<<"의 약수 : ";
	for_each(dest.cbegin(), dest.cend(), [](int n){cout << n << " ";});



copy_if는 내부적으로 _Dest 반복자에 ++ 연산을 해서 위치를 이동시킵니다. 따라서 dest list는 미리 충분한 공간을 확보해두거나
예로든 코드 처럼 back_inserter로 반복자를 넘겨주어야 합니다.



copy_n

MSDN에 등록된 copy_n에 대한 선언은 다음과 같습니다.

template<class InputIterator, class Size, class OutputIterator>
    OutputIterator copy_n(
        InputIterator  _First, 
        Size _Count,
        OutputIterator _Dest
    );


copy_n은 _First 위치에서 _Count 개수만큼 element를 _Dest에 복사합니다. 다음과 같이 사용할 수 있습니다.

  1 	copy_n(src.begin(), 3, back_inserter(dest));

find_if_not

MSDN에 등록된 find_if_not에 대한 선언은 다음과 같습니다.


template<class InputIterator, class Predicate>
    InputIterator find_if_not(
        InputIterator _First, 
        InputIterator _Last,
        BinaryPredicate _Comp
    );



_First 위치부터 _Last위치까지 _Comp를 수행해서 false를 반환하는 첫번째 위치의 반복자를 return하게 됩니다.
아래의 프로그램은 copy_if에서 사용한 프로그램을 약간 수정한 것입니다.
12의 약수가 아닌 가장 작은 자연수를 구하는 과정입니다.

	const int N=12;
	list<int> src;
	list<int> dest;
	// 데이터 초기화
	for(int i=1 ; i<=N ; i++)
		src.push_back(i);
 
	// 약수만을 복사
	copy_if(src.begin(), src.end(), back_inserter(dest), [=](int n){ return N % n == 0; });
	// 3개만 복사
	auto pos = find_if_not(src.cbegin(), src.cend(), [=](int n){ return N % n == 0; });
 
 
	// 결과 출력
	cout<<N<<"의 약수 : ";
	for_each(dest.cbegin(), dest.cend(), [](int n){cout << n << " ";});
	cout<<endl;
	cout<<N<<"의 약수가 아닌 가장 작은 자연수 : "<< *pos <<endl;


출력은 다음과 같습니다.