템플릿 (Template)

템플릿은 타입에 관계없이 일반화된 코드를 작성하기 위한 문법이다.

이 문법 자체는 비교적 간단 하다. >> template <typename T>

 

이 의미는 어떤 타입이 올지 모르겠으나, 그 타입을 T 라고 부르겠다는 의미이다.

이후에는 일반화 하려는 타입 자리에 실제 타입 대신 T를 사용하면 된다.

 

// 목적: 함수 템플릿을 이용해 두 값을 더하는 일반화된 함수 작성하기
#include <iostream>
using namespace std;

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << add(3, 5) << endl;        // 정수 더하기
    cout << add(2.5, 4.1) << endl;    // 실수 더하기
    return 0;
}

// 출력결과:
// 8
// 6.6

템플릿 클래스

함수뿐만 아니라, 클래스도 템플릿으로 사용해 일반화 할 수 있다.

#include <iostream>
using namespace std;

template <typename T>
class Array {
    T data[100];
    int size;
public:
    Array() : size(0) {}

    void add(const T& element) {
        if(size < 100)
            data[size++] = element;
    }

    void remove() {
        if(size > 0)
            size--;
    }

    void print() {
        for(int i = 0; i < size; i++)
            cout << data[i] << " ";
        cout << endl;
    }
};

STL (Standard Template Library)

컨테이너

컨테이너는 데이터를 담는 자료구조이다.

데이터를 담는 방식이나 제공하는 메서드에 따라 여러가지 컨테이너를 제공한다.

 

벡터

벡터는 배열과 매우 유사한 컨테이너이다.

특징

  • 템플릿 클래스로 구현되어 특정 타입에 종속되지 않는다
  • 삽입되는 원소 개수에 따라 내부 배열의 크기가 자동으로 조정된다.
  • 임의 접근이 가능하다. (인덱스를 통해 특정 위치에 접근 가능)
  • 삽입 / 삭제는 맨 뒤에 하는 게 좋다 (중간 삽입 / 삭제는 배열 복사가 필요해 비효율적이다.)

벡터의 선언

타입만 명시해서 선언하는 방법이 있고, 초기값까지 같이 선언하는 경우도 있다.

  • 벡터의 기본생성 및 특정값으로 초기화
#include <vector>
using namespace std;

// 1. 기본 생성 및 초기화 없이 선언
vector<int> vec1;

// 2. 특정 크기와 초기값으로 벡터 선언
vector<int> vec2(5, 10); // 크기 5, 모든 원소가 10으로 초기화

//메인 함수 생략

////////////////////////////////////////////
//리스트로 초기화

// 3. 리스트 초기화로 벡터 선언
vector<int> vec3 = {1, 2, 3, 4, 5};


////////////////////////////////////////////
// 기존 벡터를 복사해서 선언

// 다른 벡터를 기반으로 복사 초기화
vector<int> vec3 = {1, 2, 3, 4, 5};
vector<int> vec4(vec3); // vec3의 복사본 생성
//vector<int> vec4 = vec3 하면 대입이 됨

 

벡터의 동작

  •  push_back : 벡터의 맨 끝에 원소를 추가하는 메서드
vector<int> vec;
    vec.push_back(10);

 

  • pop_back : 벡터의 맨 끝에 원소를 제거하는 메서드
vector<int> vec = {10, 20, 30};
    vec.pop_back();  // 마지막 요소(30) 제거

 

  • size : 현재 백터의 크기(원소 개수)를 확인할 때 사용하는 메서드
vector<int> vec = {10, 20, 30};
    cout << "Size of vector: " << vec.size() << endl;

 

  • erase  특정 위치(또는 구간)의 원소를 제거하는 함수
 vector<int> vec = {10, 20, 30, 40, 50};

    // 두 번째 요소 제거 (index 1)
    vec.erase(vec.begin() + 1);

  // 2~4 번째 요소 제거 (index 1~3)
    vec.erase(vec.begin() + 1, vec.begin() + 3);

맵을 선언할 때는 키-값 쌍을 저장하기 위해 키 타입과 값타입 두 가지를 지정해야 한다.

이 두 타입은 동일할 수도 있고, 서로 다를 수도 있으며, 키 타입은 비교 연산이 가능해야 한다.

  • 기본적인 map 선언 및 사용
#include <iostream>
#include <map>

using namespace std;

// 정수 키와 문자열 값을 저장하는 map 예제
int main() {
    map<int, string> studentMap;

    // 요소 추가
    studentMap[101] = "Alice";
    studentMap[102] = "Bob";
    studentMap[103] = "Charlie";

    // 요소 출력
    for (const auto& pair : studentMap) {
        cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
    }

    return 0;
}

 

맵의 동작

map은 key 순으로 오름차순 정렬된다.

이는 사용자가 별도로 정렬을 수행하지 않아도, 삽입 및 삭제가 이루어질 때마다 내부적으로 정렬 상태를 유지하기 때문이다.

 

  • find() : find 메서드를 사용하면 특정 키가 map에 존재하는지 확일할 수 있다. find는 키가 존재하면 해당 키의 이터레이터를 반환하고, 존재하지 않으면 map.end()를 반환 한다.
#include <iostream>
#include <map>

using namespace std;

int main() {
    map<int, string> myMap = {
        {1, "Apple"},
        {2, "Banana"},
        {3, "Cherry"}
    };

    int key = 2;
    auto it = myMap.find(key); // 키 2를 찾기

    if (it != myMap.end()) {
        cout << "Found! Key: " << it->first << ", Value: " << it->second << endl;
    } else {
        cout << "Key " << key << " not found!" << endl;
    }

    return 0;
}

/*
출력 결과:
Found! Key: 2, Value: Banana
*/

 

  • size() : 맴에 키값 쌍의 개수를 반환하는 함수이다.
#include <iostream>
#include <map>

using namespace std;

int main() {
    map<int, string> myMap;

    // 요소 추가
    myMap[1] = "Apple";
    myMap[2] = "Banana";
    myMap[3] = "Cherry";

    // 현재 크기 출력
    cout << "Map size: " << myMap.size() << endl;

    return 0;
}

/*
출력 결과:
Map size: 3
*/

 

  • erase(key) : 맵의 특정 key를 가진 요소만 삭제
#include <iostream>
#include <map>

using namespace std;

int main() {
    map<int, string> myMap = {
        {1, "Apple"},
        {2, "Banana"},
        {3, "Cherry"}
    };

    cout << "Before erase, size: " << myMap.size() << endl;

    // 특정 키 삭제
    myMap.erase(2);

    cout << "After erase(2), size: " << myMap.size() << endl;

    // 남은 요소 출력
    for (const auto& pair : myMap) {
        cout << "Key: " << pair.first << ", Value: " << pair.second << endl;
    }

    // 존재하지 않는 키 삭제 시도
    int removed = myMap.erase(40);

    if (removed == 0) {
        cout << "Key 40 not found. No deletion performed." << endl;
    }


    return 0;
}

 

  • clear : 맵에 있는 모든 원소를 삭제하는 함
#include <iostream>
#include <map>

using namespace std;

int main() {
    map<int, string> myMap = {
        {1, "Apple"},
        {2, "Banana"},
        {3, "Cherry"}
    };

    cout << "Before clear, size: " << myMap.size() << endl;

    // 모든 요소 삭제
    myMap.clear();

    cout << "After clear, size: " << myMap.size() << endl;

    return 0;
}

 

+ Recent posts