algorithm_copy
algorithm_copy (요소 복사)
std::copy는 소스 범위 [first, last)의 요소들을 d_first에서 시작하는 목적지 범위로 복사해요. std::copy_if는 조건을 만족하는 요소만 복사해요.
출처: cppreference
본문
std::copy와 std::copy_if는 <algorithm> 헤더에 정의되어 있어요.
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last,
OutputIt d_first );
template< class InputIt, class OutputIt, class UnaryPred >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred );
copy— 소스 범위의 모든 요소를first부터last까지 순서대로 복사해요.d_first가 소스 범위 안에 있으면 동작이 정의되지 않아요.copy_if— 술어pred가 참을 반환하는 요소만 복사해요. 소스와 목적지 범위가 겹치면 동작이 정의되지 않아요.copy_if는 안정적이라 복사된 요소들의 상대적 순서가 유지돼요.
병렬 실행 정책을 받는 오버로드도 있어요.
반환값 (Return value)
목적지 범위의 끝(past-the-end) 반복자예요.
복잡도 (Complexity)
N을 std::distance(first, last)라고 하면 copy는 정확히 N번 배정하고, copy_if는 정확히 N번 pred를 적용하고 최대 N번 배정해요.
참고 (Notes)
실제 구현은 값 타입이 TriviallyCopyable이고 반복자 타입이 ContiguousIterator를 만족하면 여러 번 배정하는 대신 std::memmove 같은 벌크 복사 함수를 사용해요.
왼쪽으로 복사할 땐 std::copy, 오른쪽으로 복사할 땐 std::copy_backward가 적합해요.
예제 (Example)
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> from_vector(10);
std::iota(from_vector.begin(), from_vector.end(), 0);
std::vector<int> to_vector;
std::copy(from_vector.begin(), from_vector.end(), std::back_inserter(to_vector));
std::cout << "to_vector contains: ";
std::copy(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::cout << "odd numbers in to_vector are: ";
std::copy_if(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int x) { return x % 2 != 0; });
std::cout << '\n';
std::cout << "to_vector contains these multiples of 3: ";
to_vector.clear();
std::copy_if(from_vector.begin(), from_vector.end(),
std::back_inserter(to_vector),
[](int x) { return x % 3 == 0; });
for (const int x : to_vector)
std::cout << x << ' ';
std::cout << '\n';
}
출력:
to_vector contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in to_vector are: 1 3 5 7 9
to_vector contains these multiples of 3: 0 3 6 9
가능한 구현 (Possible implementation)
template<class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
for (; first != last; (void)++first, (void)++d_first)
*d_first = *first;
return d_first;
}
template<class InputIt, class OutputIt, class UnaryPred>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred)
{
for (; first != last; ++first)
if (pred(*first))
{
*d_first = *first;
++d_first;
}
return d_first;
}