C++ STL 정리 (1편) — 컨테이너

2026. 6. 1. 16:03·블로그, 컴퓨터/Cheatsheets

C++ STL cheatsheet

C++를 쓰다 보면 표준 라이브러리(STL)를 얼마나 잘 아느냐에 따라 코드 품질이 꽤 달라집니다. 직접 자료구조를 구현하지 않아도 되고, 이미 최적화가 잘 된 구현을 그냥 쓰면 됩니다. 그런데 너무 그 header 종류가 방대해서 맨날 까먹고... 정리를 해야겠다고 마음을 먹었습니다.

STL은 크게 컨테이너, 알고리즘, 이터레이터, 유틸리티로 나뉩니다. 1편에서는 컨테이너를 정리합니다.


헤더 포함

각 컨테이너는 해당 헤더를 포함해야 씁니다.

#include <vector>
#include <array>
#include <deque>
#include <list>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <stack>
#include <queue>
#include <string>

vector

동적 배열입니다. 가장 자주 쓰는 컨테이너입니다. 연속된 메모리에 저장돼서 캐시 효율이 좋습니다.

#include <vector>

std::vector<int> v;
std::vector<int> v2 = {1, 2, 3, 4, 5};
std::vector<int> v3(10, 0);      // 크기 10, 초기값 0
std::vector<int> v4(v2);         // 복사 생성

// 원소 추가
v.push_back(10);
v.emplace_back(20);              // push_back보다 효율적 (직접 생성)

// 접근
v[0];                            // 범위 검사 없음
v.at(0);                         // 범위 검사 있음 (예외 발생)
v.front();                       // 첫 번째
v.back();                        // 마지막

// 크기
v.size();                        // 원소 수
v.capacity();                    // 할당된 용량
v.empty();                       // 비어있는지
v.reserve(100);                  // 용량 미리 확보 (재할당 방지)
v.resize(20);                    // 크기 변경
v.shrink_to_fit();               // 여분 용량 반납

// 삭제
v.pop_back();                    // 마지막 제거
v.erase(v.begin());              // 특정 위치 제거
v.erase(v.begin(), v.begin()+3); // 범위 제거
v.clear();                       // 전체 제거

// 삽입
v.insert(v.begin() + 2, 99);     // 특정 위치에 삽입

// 이터레이터
for (auto& x : v) { ... }        // 범위 기반 for
for (auto it = v.begin(); it != v.end(); ++it) { ... }

push_back vs emplace_back — emplace_back은 인수를 그대로 전달해서 컨테이너 안에서 직접 생성합니다. 임시 객체를 만들고 복사하는 push_back보다 효율적인 경우가 많습니다.


array

크기가 컴파일 시점에 고정된 배열입니다. C 스타일 배열 대신 씁니다. 스택에 할당되고 오버헤드가 없습니다.

#include <array>

std::array<int, 5> arr = {1, 2, 3, 4, 5};
std::array<int, 5> arr2;         // 초기화 안 됨

arr[0];                          // 접근
arr.at(0);                       // 범위 검사
arr.size();                      // 항상 5
arr.front();
arr.back();
arr.fill(0);                     // 전체를 0으로

deque

양방향 큐입니다. vector와 비슷하지만 앞뒤 모두 O(1)으로 삽입/삭제가 됩니다.

#include <deque>

std::deque<int> dq = {3, 4, 5};

dq.push_front(2);    // 앞에 추가
dq.push_back(6);     // 뒤에 추가
dq.pop_front();      // 앞에서 제거
dq.pop_back();       // 뒤에서 제거

dq[0];               // 임의 접근 (vector처럼)

list

이중 연결 리스트입니다. 중간 삽입/삭제가 O(1)이지만 임의 접근은 없습니다. 캐시 효율이 나쁘고 메모리 오버헤드가 있어서 실제로 쓸 일이 생각보다 적습니다.

#include <list>

std::list<int> lst = {1, 2, 3};

lst.push_back(4);
lst.push_front(0);
lst.pop_back();
lst.pop_front();

// 정렬, 역순, 중복 제거
lst.sort();
lst.reverse();
lst.unique();        // 연속된 중복 제거 (정렬 후 쓰면 전체 중복 제거)

// 이터레이터로만 접근 (임의 접근 없음)
auto it = lst.begin();
std::advance(it, 2); // it를 2칸 앞으로
lst.insert(it, 99);
lst.erase(it);

map / multimap

키-값 쌍을 저장합니다. 키 기준 정렬된 상태를 유지합니다(레드블랙 트리 기반). 탐색/삽입/삭제 모두 O(log n)입니다.

#include <map>

std::map<std::string, int> m;

// 삽입
m["apple"] = 3;
m.insert({"banana", 5});
m.emplace("cherry", 7);

// 접근
m["apple"];              // 없으면 기본값으로 생성됨 (주의)
m.at("apple");           // 없으면 예외

// 탐색
auto it = m.find("apple");
if (it != m.end()) {
    std::cout << it->second;
}
m.count("apple");        // 있으면 1, 없으면 0

// 순회 (키 기준 정렬 순)
for (auto& [key, val] : m) {
    std::cout << key << ": " << val;
}

// 삭제
m.erase("apple");
m.erase(m.begin());

// 기타
m.size();
m.empty();
m.contains("apple");     // C++20

m["key"]는 키가 없으면 기본값으로 새로 만듭니다. 읽기만 하려면 find()나 at()을 씁니다.

multimap은 같은 키를 여러 개 허용합니다. [] 연산자는 없습니다.


unordered_map / unordered_multimap

해시 기반 맵입니다. 정렬은 없지만 평균 O(1) 탐색/삽입/삭제입니다. 순서가 필요 없으면 map보다 빠릅니다.

#include <unordered_map>

std::unordered_map<std::string, int> um;

um["apple"] = 3;
um.insert({"banana", 5});

auto it = um.find("apple");
um.count("apple");
um.contains("apple");    // C++20

// 버킷 관련
um.bucket_count();
um.load_factor();
um.reserve(100);         // 예상 원소 수 미리 알려줌 (재해시 방지)

사용자 정의 타입을 키로 쓰려면 해시 함수를 직접 만들어야 합니다.

struct Point { int x, y; };

struct PointHash {
    size_t operator()(const Point& p) const {
        return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);
    }
};

struct PointEqual {
    bool operator()(const Point& a, const Point& b) const {
        return a.x == b.x && a.y == b.y;
    }
};

std::unordered_map<Point, int, PointHash, PointEqual> pm;

set / multiset

정렬된 집합입니다. 중복을 허용하지 않습니다(multiset은 허용). 내부는 map과 같이 레드블랙 트리입니다.

#include <set>

std::set<int> s = {3, 1, 4, 1, 5};   // {1, 3, 4, 5} — 중복 제거, 정렬

s.insert(2);
s.erase(3);
s.find(4);                // 이터레이터 반환
s.count(1);               // 있으면 1
s.contains(1);            // C++20

// 범위 탐색
auto lower = s.lower_bound(3);    // 3 이상 첫 번째
auto upper = s.upper_bound(3);    // 3 초과 첫 번째

unordered_set

해시 기반 집합입니다. 순서 없고 평균 O(1).

#include <unordered_set>

std::unordered_set<int> us = {1, 2, 3, 4};

us.insert(5);
us.erase(3);
us.contains(2);    // C++20

stack / queue / priority_queue

어댑터 컨테이너입니다. 내부적으로 다른 컨테이너를 감쌉니다.

stack — LIFO

#include <stack>

std::stack<int> st;
st.push(1);
st.push(2);
st.top();         // 2 (제거 없이 보기)
st.pop();         // 제거만 (반환 없음)
st.empty();
st.size();

queue — FIFO

#include <queue>

std::queue<int> q;
q.push(1);
q.push(2);
q.front();        // 맨 앞
q.back();         // 맨 뒤
q.pop();

priority_queue — 최대 힙 (기본)

std::priority_queue<int> pq;         // 최대 힙
pq.push(3);
pq.push(1);
pq.push(4);
pq.top();         // 4 (가장 큰 값)
pq.pop();

// 최소 힙
std::priority_queue<int, std::vector<int>, std::greater<int>> min_pq;

string

#include <string>

std::string s = "Hello";
std::string s2(5, 'a');        // "aaaaa"

// 접근
s[0];
s.at(0);
s.front();
s.back();

// 연결
s + " World";
s += "!";
s.append(" more");

// 탐색
s.find("ll");                  // 2 (위치), npos면 없음
s.rfind("l");                  // 뒤에서 찾기
s.find_first_of("aeiou");      // 모음 중 처음 나오는 위치

// 부분 문자열
s.substr(1, 3);                // 1번 위치부터 3글자

// 변환
std::to_string(42);
std::stoi("42");
std::stod("3.14");

// 비교, 크기
s.size();
s.empty();
s.compare("Hello");

// 치환
s.replace(0, 5, "Hi");

// 제거
s.erase(1, 3);                 // 1번 위치부터 3글자 제거

컨테이너 선택 기준

상황 선택
기본 배열, 빠른 임의 접근 vector
크기 고정 배열 array
앞뒤 삽입/삭제 모두 필요 deque
중간 삽입/삭제 빈번 list
키-값, 정렬 필요 map
키-값, 속도 우선 unordered_map
중복 없는 집합, 정렬 필요 set
중복 없는 집합, 속도 우선 unordered_set
LIFO stack
FIFO queue
우선순위 큐 priority_queue

2편에서는 알고리즘, 이터레이터, 람다와 함수형 유틸리티, C++17/20 추가 유틸리티를 정리합니다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글

C++ STL 정리 (3편) — C++17/20 유틸리티  (0) 2026.06.01
C++ STL 정리 (2편) — 알고리즘, 이터레이터, 유틸리티  (0) 2026.06.01
GitHub Actions 정리 (2편) — 캐싱, Matrix, 재사용, 실전 패턴  (0) 2026.05.31
GitHub Actions 정리 (1편) — 개념, 워크플로우 구조, 트리거  (0) 2026.05.31
CMake 정리 (2편) — 서브디렉토리, 외부 라이브러리, 실용 패턴  (0) 2026.05.30
'블로그, 컴퓨터/Cheatsheets' 카테고리의 다른 글
  • C++ STL 정리 (3편) — C++17/20 유틸리티
  • C++ STL 정리 (2편) — 알고리즘, 이터레이터, 유틸리티
  • GitHub Actions 정리 (2편) — 캐싱, Matrix, 재사용, 실전 패턴
  • GitHub Actions 정리 (1편) — 개념, 워크플로우 구조, 트리거
생각사람
생각사람
지극히 사적인 연구실
  • 생각사람
    생각사람의 별장
    생각사람
  • 전체
    오늘
    어제
    • 분류 전체보기 (207)
      • 금융 (57)
        • 주식 공부 (11)
        • 파생상품 입문 (17)
        • 파생상품 기초 (15)
        • 파생상품 실전 (14)
      • 블로그, 컴퓨터 (83)
        • 프로그래밍 (16)
        • DevOps (8)
        • AI, RL, ML, ... (5)
        • 애드센스, SEO (23)
        • 임베디드 (3)
        • 컴퓨터 관련 (7)
        • Cheatsheets (21)
      • 다른 공부들 (67)
        • 읽고 쓰기 (18)
        • 수학 (15)
        • 물리 (9)
        • 사진 공부 (25)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 태그

    파생상품
    스트래들
    GIT
    웹크롤러
    옵션 투자
    벡터
    공업수학
    선물 옵션
    깃허브
    구글 애드센스
    코딩
    옵션
    c
    독후감
    Kreyszig
    c++
    슈뢰딩거 방정식
    스트랭글
    깃
    cmake
    양자역학
    오펜하이머
    github
    선형대수학
    행렬
    프로그래밍
    AI
    version control
    소니 a6000
    CheatSheet
  • hELLO· Designed By정상우.v4.10.6
생각사람
C++ STL 정리 (1편) — 컨테이너
상단으로

티스토리툴바