C++ 표준 라이브러리의 std::swap_ranges 알고리즘을 사용하면 벡터(vector)와 리스트(list)처럼 서로 다른 컨테이너 사이에서도 특정 구간의 요소들을 손쉽게 맞바꿀 수 있습니다. 이번 글에서는 swap_ranges 함수의 기본 개념과 실제 사용 예제를 통해 두 컨테이너의 부분 범위를 교환하는 방법을 알아보겠습니다.
swap_ranges란?
std::swap_ranges는 <algorithm> 헤더에 정의된 함수로, 첫 번째 범위 [first1, last1)의 요소들과 second 인자가 가리키는 위치부터 시작하는 같은 길이의 범위를 순서대로 하나씩 교환합니다. 서로 다른 타입의 컨테이너라도 요소 타입이 호환된다면 자유롭게 사용할 수 있다는 점이 큰 장점입니다.
예제 코드
아래 예제에서는 정수형 벡터와 리스트를 준비한 뒤, 벡터의 처음 세 개 요소와 리스트의 처음 세 개 요소를 서로 교환합니다.
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main() {
vector<int> v = { -10, -15, -30, 20, 500 };
list<int> lt = { 10, 50, 30, 100, 50 };
// 벡터의 처음 3개 요소와 리스트의 처음 3개 요소를 교환
swap_ranges(v.begin(), v.begin() + 3, lt.begin());
for (int n : v)
cout << n << ' ';
cout << '\n';
for (int n : lt)
cout << n << ' ';
cout << endl;
return 0;
}실행 결과
10 50 30 20 500 -10 -15 -30 100 50
결과 분석
교환이 수행되기 전 벡터는 {-10, -15, -30, 20, 500}, 리스트는 {10, 50, 30, 100, 50}이었습니다. swap_ranges(v.begin(), v.begin() + 3, lt.begin()) 호출 후 다음과 같은 변화가 일어났습니다.
- 벡터의 앞 세 요소(-10, -15, -30)가 리스트의 앞 세 요소(10, 50, 30)와 맞바뀌어, 벡터는
{10, 50, 30, 20, 500}이 되었습니다. - 리스트는 앞 세 요소가 벡터의 값으로 대체되어
{-10, -15, -30, 100, 50}이 되었고, 네 번째와 다섯 번째 요소(100, 50)는 그대로 유지되었습니다.
주의 사항
swap_ranges를 사용할 때는 몇 가지 유의해야 할 점이 있습니다.
- 두 번째 컨테이너에는 첫 번째 범위의 길이만큼 최소한의 유효한 요소가 존재해야 합니다. 그렇지 않으면 정의되지 않은 동작(undefined behavior)이 발생할 수 있습니다.
- 범위가 서로 겹치는 경우에도 동작은 가능하지만, 의도하지 않은 결과가 나올 수 있으므로 겹치지 않는 범위에서 사용하는 것이 안전합니다.
- 요소 타입은 복사 할당이 가능해야 하며, 일반적으로 이동(movable) 또는 복사(copyable) 가능한 타입이어야 합니다.
마무리
std::swap_ranges는 반복자만으로 두 컨테이너의 구간을 교환할 수 있는 간결하고 효율적인 도구입니다. 벡터와 리스트처럼 내부 구조가 완전히 다른 컨테이너 간에도 문제없이 동작하므로, 부분 데이터 교환이 필요한 상황에서 직접 반복문을 작성하는 것보다 훨씬 깔끔하고 오류 가능성이 낮은 코드를 작성할 수 있습니다.