----------------
title : C++ 레퍼런스 - std::copy 와 copy_if (<algorithm>)
cat_title : copy, copy_if
ref_title : copy, copy_if, std::copy, std::copy_if
path : /C++ Reference/algorithm
publish_date : 2020-01-30
----------------

##@ cpp-ref-start

#@ copy, copy_if

`<algorithm>` 에 정의됨

```cpp-formatted
// 참고로 C++ 20 부터 모두 constexpr 함수 이다.
template <class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, OutputIt d_first);

template <class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last, OutputIt d_first,
                 UnaryPredicate pred);
```

**범위 내의 원소들을 다른 장소에 복사한다.**

`copy` 함수는 `first` 부터 `last` 전 까지의 모든 원소들을 `d_first` 부터 시작하는 곳에 복사한다. `copy_if` 의 경우 `pred` 가 `true` 를 리턴하는 원소만 복사하게 된다. 이 때 원소들의 상대적인 순서는 유지된다.

### 인자들

* `first, last` : 원소들의 범위를 나타내는 반복자. (각각 첫 번째 원소와 마지막 원소 바로 다음을 가리킴)
* `d_first`	: 복사한 원소들을 저장할 곳의 시작점을 나타내는 반복자
* `pred` : 조건을 확인하는 함수. 이 때 반복자들이 가리키는 원소 `v` 에 대해서 `pred(v)` 는 반드시 `bool` 로 변환될 수 있어야만 한다. 에를 들어서 `bool Pred(const Elem& v)` 와 같이 말이다.

### 리턴값

복사된 곳의 마지막 원소 바로 다음을 가리키는 반복자.

### 구현 예시

#### copy

```cpp-formatted
template <class InputIt, class OutputIt>
OutputIt copy(InputIt first, InputIt last, OutputIt d_first) {
  while (first != last) {
    *d_first++ = *first++;
  }
  return d_first;
}
```

#### copy_if

```cpp-formatted
template <class InputIt, class OutputIt, class UnaryPredicate>
OutputIt copy_if(InputIt first, InputIt last, OutputIt d_first,
                 UnaryPredicate pred) {
  while (first != last) {
    if (pred(*first)) *d_first++ = *first;
    first++;
  }
  return d_first;
}
```

#### 실행 예제

```cpp-formatted
#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
 
int main()
{
    std::vector<int> from_vector(10);
    // 0 부터 9 까지 원소들을 from_vector 에 집어넣는다.
    std::iota(from_vector.begin(), from_vector.end(), 0);
 
    std::vector<int> to_vector;
    // from_vector 의 원소들을 to_vector 에 복사한다.
    std::copy(from_vector.begin(), from_vector.end(),
              std::back_inserter(to_vector));
    std::cout << "to_vector contains: ";
 
    // to_vector 의 원소들을 표준 출력 객체(std::cout) 에 전달한다. 
    std::copy(to_vector.begin(), to_vector.end(),
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}
```

```exec
to_vector contains: 0 1 2 3 4 5 6 7 8 9
```

### 참고 자료

* `copy_backward` : 범위 내의 원소들을 뒤에서 부터 복사한다. 하지만 원소들 간의 상대적 순서는 유지. (즉 마지막 원소 부터 복사하되, 마지막 원소는 맨 마지막 칸에 넣는다.)
* `reverse_copy` : 범위 내의 원소들을 거꾸로 복사한다.
* `copy_n` : 특정 개수의 원소만 복사한다.
* `fill` : 특정 값으로 범위를 채운다.
* `remove_copy`, `remove_copy_if` : 특정 조건을 만족하는 원소들만 **빼고** 복사한다.