나만의 작은 도서관
[C++][STL Container] 비교 연산자와 반복자 지원 본문
STL Container의 공통된 기능 : 비교 연산자와 반복자
STL 컨테이너들은 공통적으로 비교 연산자와 반복자를 지원한다. 단, 컨테이너 어뎁터에 반복자를 지원하지 않는 것처럼 일부 컨테이너들은 지원하지 않는 경우가 있다.
비교 연산자 오버로딩 지원
순서 개념이 없는 unordered_xxx 계열의 컨테이너가 크기 비교(<, <=, >, >=) 연산자를 제공하지 않는다는 점을 제외하면 모든 컨테이너가 비교 연산자를 지원한다. 컨테이너들은 비교할 때 내부적으로 "std::lexicographical_compare"를 이용하여 사전식(lexicographical order)으로 비교한다.
+) 참고로, 연관 컨테이너는 값과 상관없이 오로지 key를 기준으로 비교한다.
제공하는 연산자 종류는 아래와 같다.
operator== | lhs == rhs시 true, 아니면 false |
operator!= | lhs != rhs시 true, 아니면 false |
operator< | lhs < rhs시 true, 아니면 false |
operator<= | lhs <= rhs시 true, 아니면 false |
operator> | lhs > rhs시 true, 아니면 false |
operator>= | lhs >= rhs시 true, 아니면 false |
사전순(lexicographical order)이란?
사전순은 첫 번째 기준으로 "값"을, 두 번째 기준으로 "컨테이너 크기"를 비교하는 오름차순 정렬 방식을 말한다. 예시로 들면 아래와 같다.
{1, 2, 3} vs {1, 2, 4} => 3 < 4 이므로 왼쪽이 작다 (true)
{1, 2, 3} vs {1, 2, 3, 0} => size(3) < size(4)이므로 왼쪽이 작다 (true)
operator <=>(C++20~)
C++20부터 '=='연산자를 제외한 나머지 연산자들을 삭제하고 '<=>'하나로 기능을 통합하였다. <=>은 첫 번째 인자를 기준으로 두 인수의 관계에 따라 아래와 같이 리턴한다.
- 작다면 less(-1)
- 같으면 equal(0), equivalent (0)
- 크다면 greater(1)
- 알 수 없다면 unordered(-128)
컨테이너별 비교 방식 정리
컨테이너 | 비교 방식 |
vector, deque, list, array, string | 사전순 비교 (lexicographical order) |
set, multiset | 내부 정렬 기준에 따라 사전순 비교 |
map, multimap | (key, value) 쌍을 key 기준으로 사전순 비교 |
unordered_set, unordered_map | ❌ 대소 비교 연산자 없음 (정렬되지 않음) |
반복자 지원
STL 컨테이너 중 반복자(iterator)를 지원하지 않는 컨테이너는 없다. 즉, 모든 표준 컨테이너(std::container)는 반복자를 지원한다.
하지만, 일반적인 컨테이너와 다르게 동작하거나 부분적으로만 제공하는 컨테이너는 존재한다. 이에 대해 정리하면 아래와 같다.
컨테이너별 반복자 지원 정리
컨터이너 종류 | 컨테이너 | 반복자 지원 여부 | 특징 |
시퀀스 컨테이너 | std::vector, std::deque, std::list, std::array | ✅ 지원 | 모든 요소를 순차적으로 접근 가능 |
연관 컨테이너 (정렬 O) | std::set, std::map, std::multiset, std::multimap | ✅ 지원 | 정렬된 순서대로 접근 가능 |
연관 컨테이너(정렬 X) | std::unordered_set, std::unordered_map, std::unordered_multiset, std::unordered_multimap | ✅ 지원 | 정렬되지 않은 순서로 접근 |
컨테이너 어뎁터 | std::stack, std::queue, std::priority_queue | ❌ 반복자 직접 접근 불가 | 내부적으로 컨테이너를 사용하지만, 반복자 제공 X |
반복자 지원 여부 예제
#include <stack>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3};
std::stack<int> s;
// 벡터는 반복자 사용 가능
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " "; // 1 2 3
}
std::cout << "\n";
// 스택에 원소 추가
s.push(10);
s.push(20);
s.push(30);
// ❌ 아래 코드: std::stack은 반복자 지원 X (컴파일 오류)
// for (auto it = s.begin(); it != s.end(); ++it) {
// std::cout << *it << " ";
// }
return 0;
}
참고 자료
'C++ > 문법 및 메소드(STL)' 카테고리의 다른 글
[C++][Class] 클래스(Class) (0) | 2025.03.25 |
---|---|
[C++] 동적 할당 (0) | 2025.03.19 |
[C++][STL Container] 컨테이너 어뎁터 (0) | 2025.03.18 |
[C++][STL Container] 연관 컨테이너 (set/map, multiset/multimap, unordered_set/unordered_map) (0) | 2025.03.17 |
[C++][STL Container] 시퀀스 컨테이너 #4. 배열(Array) (0) | 2025.03.15 |