C++ STL에는 이름 그대로 데이터를 복사하는 데 사용되는 copy() 계열의 함수들이 있습니다. 이 함수들은 모두 <algorithm> 헤더 파일에 정의되어 있으며, 기능과 매개변수 구성이 서로 다릅니다. 이 글에서는 각 함수의 특징과 사용법을 하나씩 자세히 살펴보겠습니다.
1. std::copy(start_i1, end_i1, start_i2)
가장 기본적인 복사 함수로, 지정한 범위 내의 요소들을 한 반복자(iterator)에서 다른 반복자로 복사합니다. 세 가지 인자를 받습니다.
- start_i1 − 복사를 시작할 원본 반복자(i_1)의 첫 번째 요소를 가리킵니다.
- end_i1 − 복사가 끝나는 원본 반복자(i_1)의 마지막 위치를 가리킵니다.
- start_i2 − 요소가 붙여넣어질 대상 반복자(i_2)의 시작 위치를 가리킵니다.
반환값: 복사가 완료된 대상 반복자(i_2)의 끝 위치를 가리키는 반복자를 반환합니다.
예제 코드
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
// 벡터 v1 생성
vector<int> vec_1 = { 10, 20, 30, 40, 50 };
// 크기가 지정된 빈 벡터 선언
vector<int> vec_2(6);
// copy() 함수를 사용해 vec_2에 복사
copy(vec_1.begin(), vec_1.begin()+4, vec_2.begin());
// 새 벡터 출력
cout<<"Elements in vector v2 copied from v1: ";
for(int i=0; i<4; i++){
cout<<vec_2[i] << " ";
}
}실행 결과
Elements in vector v2 copied from v1: 10 20 30 40
2. std::copy_n(start_i1, total, start_i2)
이 함수 역시 한 반복자에서 다른 반복자로 데이터를 복사하지만, 시작 위치부터 몇 개의 요소를 복사할지 개수를 직접 지정한다는 점이 다릅니다. 세 가지 인자를 받습니다.
- start_i1 − 복사를 시작할 원본 반복자(i_1)의 첫 번째 요소를 가리킵니다.
- total − start_i1이 가리키는 위치부터 복사할 요소의 개수를 의미합니다. 양수와 음수 모두 전달할 수 있지만, 음수가 들어오면 아무 작업도 수행하지 않습니다.
- start_i2 − 요소가 복사될 대상 반복자(i_2)의 시작 위치를 가리킵니다.
반환값: 복사가 완료된 대상 반복자(i_2)의 끝 위치를 가리키는 반복자를 반환합니다.
예제 코드
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
// 벡터 v1 생성
vector<int> vec_1 = { 10, 20, 30, 40, 50 };
// 크기가 지정된 빈 벡터 선언
vector<int> vec_2(6);
// copy_n() 함수를 사용해 vec_2에 4개 요소 복사
copy_n(vec_1.begin(), 4, vec_2.begin());
// 새 벡터 출력
cout<<"Elements in vector v2 copied from v1: ";
for(int i=0; i<4; i++){
cout<<vec_2[i] << " ";
}
}실행 결과
Elements in vector v2 copied from v1: 10 20 30 40
3. std::copy_if(start_i1, end_i1, start_i2, 조건 함수)
이 함수는 네 번째 인자로 전달된 조건을 만족하는 요소만 골라서 지정한 범위 내에서 복사합니다. 즉, 조건부 복사가 가능하다는 것이 가장 큰 특징입니다. 네 가지 인자를 받습니다.
- start_i1 − 복사를 시작할 원본 반복자(i_1)의 첫 번째 요소를 가리킵니다.
- end_i1 − 복사가 끝나는 원본 반복자(i_1)의 마지막 위치를 가리킵니다.
- start_i2 − 요소가 복사될 대상 반복자(i_2)의 시작 위치를 가리킵니다.
- 조건 함수(Boolean function) − 범위에 적용할 조건을 담은 함수입니다. 반환 타입이 불리언(true/false)이며, 반환값이 true인 요소만 대상에 복사됩니다.
반환값: 복사가 완료된 대상 반복자(i_2)의 끝 위치를 가리키는 반복자를 반환합니다.
예제 코드
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
// 벡터 v1 생성
vector<int> vec_1 = { 10, 21, 30, 40, 57 };
// 크기가 지정된 빈 벡터 선언
vector<int> vec_2(6);
// copy_if() 함수로 짝수만 vec_2에 복사
copy_if(vec_1.begin(), vec_1.end(), vec_2.begin(), [](int i){return i%2==0;});
// 새 벡터 출력
cout<<"Elements in vector v2 copied from v1: ";
for(int i=0; i<4; i++){
cout<<vec_2[i] << " ";
}
}실행 결과
Elements in vector v2 copied from v1: 10 30 40 0
람다식 [] (int i){ return i%2==0; }을 통해 짝수인 요소만 선택적으로 복사된 것을 확인할 수 있습니다.
4. std::copy_backward(start_i1, end_i1, end_i2)
이 함수는 지정한 범위의 데이터를 뒤에서부터(역방향으로) 복사합니다. 대상 반복자의 끝 위치부터 앞쪽으로 요소를 채워 넣기 때문에, 기존 데이터를 덮어쓰지 않고 뒤로 밀어내며 복사해야 할 때 유용합니다. 세 가지 인자를 받습니다.
- start_i1 − 복사를 시작할 원본 반복자(i_1)의 첫 번째 요소를 가리킵니다.
- end_i1 − 복사가 끝나는 원본 반복자(i_1)의 마지막 위치를 가리킵니다.
- end_i2 − 요소가 복사될 대상 반복자(i_2)의 끝 위치를 가리킵니다. 일반 복사와 달리 끝 위치를 지정한다는 점에 주의하세요.
반환값: 복사가 완료된 대상 반복자(i_2)의 시작 위치를 가리키는 반복자를 반환합니다.
예제 코드
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
// 벡터 v1 생성
vector<int> vec_1 = { 10, 21, 30, 40, 57, 67 };
// 크기가 지정된 빈 벡터 선언
vector<int> vec_2(6);
// copy_backward() 함수를 사용해 vec_2에 복사
copy_backward(vec_1.begin(), vec_1.end()+4, vec_2.begin()+5);
// 새 벡터 출력
cout<<"Elements in vector v2 copied from v1: ";
for(int i=0; i<vec_2.size(); i++){
cout<<vec_2[i] << " ";
}
}실행 결과
Elements in vector v2 copied from v1: 0 10 21 30 40 0
마무리
지금까지 C++ STL에서 제공하는 네 가지 복사 함수를 알아보았습니다. 상황에 맞게 함수를 선택하면 더욱 효율적이고 안전한 코드를 작성할 수 있습니다.
- std::copy(): 범위를 지정해 순방향으로 복사할 때
- std::copy_n(): 복사할 개수를 직접 지정할 때
- std::copy_if(): 특정 조건을 만족하는 요소만 복사할 때
- std::copy_backward(): 뒤에서부터 역방향으로 복사할 때
모든 함수는 <algorithm> 헤더에 포함되어 있으므로, 사용 전 반드시 해당 헤더를 포함해야 합니다.