algorithm_copy

algorithm_copy (요소 복사)

std::copy는 소스 범위 [first, last)의 요소들을 d_first에서 시작하는 목적지 범위로 복사해요. std::copy_if는 조건을 만족하는 요소만 복사해요.

출처: cppreference

본문

std::copystd::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)

Nstd::distance(first, last)라고 하면 copy는 정확히 N번 배정하고, copy_if는 정확히 Npred를 적용하고 최대 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;
}

더 알아보기 (Learn more)

cppreference