본문 바로가기

C++/STL

erase 계열 함수...

[1. 개요]

STL 컬렉션 들의 멤버 함수 erase() 의 리턴 값의 의미하는 바가 무엇인가?

  • erase 의 입력으로 사용 된, 반복자의 다음위치를 가리키는 iterator 가 반환된다.

[2. 예제]

#include <iostream>
#include <list>
#include <vector>
#include <map>
#include <unordered_set>

std::vector<int> vec;
std::list<int> lst;
std::map<int, int> kv;
std::unordered_set<int> uos;

void print_vec()
{
    std::cout << "Vec: ";
    for (const auto v : vec) {
        std::cout << v << " ";
    }
    std::cout << std::endl;
}

void print_list()
{
    std::cout << "List: ";
    for (const auto v : lst) {
        std::cout << v << " ";
    }
    std::cout << std::endl;
}

void print_map()
{
    std::cout << "Map: ";
    for (const auto vv : kv) {
        std::cout << "[" << vv.first << ", " << vv.second << "] ";
    }
    std::cout << std::endl;
}

void print_set()
{
    std::cout << "Set: ";
    for (const auto s : uos) {
        std::cout << s << " ";
    }
    std::cout << std::endl;
}

void erase_vec()
{
    auto itr0 = vec.begin();
    itr0 += 4;
    std::cout << "Vec: " << *itr0 << " -> ";
    auto itr1 = vec.erase(itr0);
    std::cout << *itr0 << " " << *itr1 << std::endl;
}

void erase_list()
{
    auto itr0 = lst.begin();
    itr0++; itr0++; itr0++; itr0++;
    std::cout << "List: " << *itr0 << " -> ";
    auto itr1 = lst.erase(itr0);
    std::cout << *itr0 << " " << *itr1 << std::endl;
}

void erase_map()
{
    auto itr0 = kv.find(5);
    std::cout << "Map: [" << itr0->first << ", " << itr0->second << "] -> ";
    auto itr1 = kv.erase(itr0);
    std::cout << "[" << itr0->first << ", " << itr0->second << "] ";
    std::cout << "[" << itr1->first << ", " << itr1->second << "] ";
    std::cout << std::endl;
}

void erase_set()
{
    auto itr0 = uos.find(5);
    std::cout << "Set: " << *itr0 << " -> ";
    auto itr1 = uos.erase(itr0);
    std::cout << *itr0 << " " << *itr1 << std::endl;
}

int main()
{
    for (int i=1; i<=10; i++) {
        vec.push_back(i);
        lst.push_back(i);
        kv.emplace(i, i*i);
        uos.insert(i);
    }

    print_vec();
    print_list();
    print_map();
    print_set();
    std::cout << std::endl;

    erase_vec();
    erase_list();
    erase_map();
    erase_set();
    std::cout << std::endl;

    print_vec();
    print_list();
    print_map();
    print_set();

    return 0;
}
출력
Vec: 1 2 3 4 5 6 7 8 9 10
List: 1 2 3 4 5 6 7 8 9 10
Map: [1, 1] [2, 4] [3, 9] [4, 16] [5, 25] [6, 36] [7, 49] [8, 64] [9, 81] [10, 100]
Set: 10 9 8 7 6 5 4 3 2 1

Vec: 5 -> 6 6
List: 5 -> 5 6
Map: [5, 25] -> [5, 25] [6, 36]
Set: 5 -> 5 4

Vec: 1 2 3 4 6 7 8 9 10
List: 1 2 3 4 6 7 8 9 10
Map: [1, 1] [2, 4] [3, 9] [4, 16] [6, 36] [7, 49] [8, 64] [9, 81] [10, 100]
Set: 10 9 8 7 6 4 3 2 1


Vector 의 경우, itr0 와 itr1 은 서로 같은 원소를 가리킨다.

  • erase() 호출 후, 
  • itr0 은 5에 해당하는 원소가 제거 된 뒤, vector 의 5번째 위치를 가리키고 있고,
  • itr1 은 제거 전, 5에 해당하는 원소의 다음 위치를 가리키고 있기 때문에,
  • erase() 후 에 같은 값을 참조하게 되는 것 이다.

Vector 와 List 는 선형 자료 구조이지만,

  • Vector 는 항상 연속된 메모리 공간에 있어야하지만,
  • List 는 그럴 필요가 없다.

따라서, List 와 비선형 자료구조인 Map 과 Set 은 itr0 와 itr1 이 서로 다른 데이터를 참조하게 되는 것 이다. 

'C++ > STL' 카테고리의 다른 글

map 과 unordered_map 의 차이점.  (0) 2024.10.23
chrono 타이머  (0) 2024.10.07
set vs multiset  (0) 2024.08.31
priority_queue  (0) 2022.09.08