이 튜토리얼에서는 C++의 연산자 오버로딩(Operator Overloading)을 활용하여 vector, map, pair의 내용을 손쉽게 출력하는 방법을 알아보겠습니다.
연산자 오버로딩이란 기존 연산자에 새로운 기능을 정의하여, 사용자가 정의한 객체(User-defined Object)에 대해서도 기본 타입처럼 자연스럽게 동작하도록 만드는 기능입니다. 이를 활용하면 cout << vec;처럼 컨테이너 전체를 한 줄로 깔끔하게 출력할 수 있습니다.
예제 코드
1. Vector 출력하기
vector<T> 타입에 대해 << 연산자를 오버로딩하면, 반복문 없이 벡터의 모든 요소를 배열 형태로 출력할 수 있습니다.
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v){
os << "[";
for (int i = 0; i < v.size(); ++i) {
os << v[i];
if (i != v.size() - 1)
os << ", ";
}
os << "]\n";
return os;
}
int main() {
vector<int> vec{ 4, 2, 17, 11, 15 };
cout << vec;
return 0;
}
출력 결과
[4, 2, 17, 11, 15]
2. Map 출력하기
map<T, S>은 키(key)와 값(value)의 쌍으로 구성되므로, 범위 기반 for문을 사용해 각 요소를 키 : 값 형태로 출력하도록 오버로딩할 수 있습니다.
#include <iostream>
#include <map>
using namespace std;
template <typename T, typename S>
ostream& operator<<(ostream& os, const map<T, S>& v){
for (auto it : v)
os << it.first << " : "
<< it.second << "\n";
return os;
}
int main(){
map<char, int> mp;
mp['b'] = 3;
mp['d'] = 5;
mp['a'] = 2;
cout << mp;
}
출력 결과
a : 2 b : 3 d : 5
map은 내부적으로 키를 기준으로 정렬되어 저장되기 때문에, 삽입 순서와 무관하게 항상 키 순서대로(a → b → d) 출력됩니다.
3. Pair 출력하기
pair<T, S> 역시 first와 second 멤버를 활용해 튜플 형태로 출력하도록 만들 수 있습니다.
#include <iostream>
using namespace std;
template <typename T, typename S>
ostream& operator<<(ostream& os, const pair<T, S>& v){
os << "(";
os << v.first << ", "
<< v.second << ")";
return os;
}
int main(){
pair<int, int> pi{ 45, 7 };
cout << pi;
return 0;
}
출력 결과
(45, 7)
정리
연산자 오버로딩을 활용하면 디버깅 시 컨테이너의 내용을 매번 반복문으로 작성하지 않고도 직관적인 형태로 출력할 수 있습니다. 위 예제들은 모두 템플릿(template)으로 작성되었기 때문에 int, string 등 다양한 타입에 그대로 재사용할 수 있다는 장점이 있습니다.