C++ 표준 라이브러리 컨테이너

표준 라이브러리는 관련 개체 컬렉션을 저장할, 형식이 안전한 다양한 컨테이너를 제공합니다. 컨테이너는 클래스 템플릿입니다. 컨테이너 변수를 선언할 때 컨테이너가 보유할 요소의 형식을 지정합니다. 컨테이너는 이니셜라이저 목록을 사용하여 생성할 수 있습니다. 요소를 추가 및 제거하고 다른 작업을 수행하기 위한 멤버 함수가 있습니다.

반복기를 사용하여 컨테이너의 요소를 반복하고 개별 요소에 액세스합니다. 멤버 함수와 연산자 및 전역 함수를 사용하여 반복기를 명시적으로 사용할 수 있습니다. 예를 들면 range-for 루프를 암시적으로 사용할 수도 있습니다. 모든 C++ 표준 라이브러리 컨테이너에 대한 반복기에 공통적인 인터페이스가 있지만 각 컨테이너에서 자체적으로 특수화된 반복기를 정의합니다.

컨테이너는 시퀀스 컨테이너, 연관 컨테이너 및 컨테이너 어댑터의 세 가지 범주로 나눌 수 있습니다.

시퀀스 컨테이너

시퀀스 컨테이너는 지정된 요소가 삽입된 순서를 유지합니다.

vector 컨테이너는 배열처럼 동작하지만 필요에 따라 자동으로 증가할 수 있습니다. 임의로 액세스되고 지속적으로 저장되며 길이가 매우 유연하게 조정됩니다. 따라서 vector는 대부분의 애플리케이션에 대한 기본 시퀀스 컨테이너입니다. 사용할 시퀀스 컨테이너의 종류에 대해 확실히 모르는 경우 벡터를 사용하여 시작합니다. 자세한 내용은 클래스를 참조 vector 하세요.

array 컨테이너에는 몇 가지 장점이 vector있지만 길이는 유연하지 않습니다. 자세한 내용은 클래스를 참조 array 하세요.

deque(양쪽구 큐) 컨테이너를 사용하면 컨테이너의 시작과 끝에 빠르게 삽입하고 삭제할 수 있습니다. 임의 vector액세스 및 유연한 길이의 장점을 공유하지만 연속되지는 않습니다. 자세한 내용은 클래스를 참조 deque 하세요.

list 컨테이너는 양방향 액세스, 빠른 삽입 및 컨테이너의 어디에서나 빠른 삭제를 가능하게 하는 이중으로 연결된 목록이지만 컨테이너의 요소에 임의로 액세스할 수는 없습니다. 자세한 내용은 클래스를 참조 list 하세요.

forward_list 컨테이너는 list의 전방향 액세스 버전인 단일 연결 목록입니다. 자세한 내용은 클래스를 참조 forward_list 하세요.

연관 컨테이너

연관 컨테이너에서 요소는 미리 정의된 순서(예: 오름차순 정렬)로 삽입됩니다. 순서가 지정되지 않은 연관 컨테이너도 사용할 수 있습니다. 연관 컨테이너를 맵 및 집합의 두 하위 집합으로 그룹화할 수 있습니다.

map은 사전이라고도 하며 키/값 쌍으로 구성됩니다. 키는 시퀀스의 순서를 지정하는 데 사용되며, 값이 해당 키에 연결됩니다. 예를 들어, map은 텍스트로 된 모든 고유한 단어를 나타내는 키와 각 단어가 텍스트에 표시되는 횟수를 나타내는 해당 값을 포함할 수 있습니다. map의 순서가 지정되지 않은 버전은 unordered_map입니다. 자세한 내용은 클래스 및unordered_map클래스를 참조map하세요.

set은 고유 요소의 오름차순 컨테이너이고, 값이 키입니다. set의 순서가 지정되지 않은 버전은 unordered_set입니다. 자세한 내용은 클래스 및unordered_set클래스를 참조set하세요.

mapset를 사용하여 키 또는 요소의 인스턴스를 컨테이너에 하나만 삽입할 수 있습니다. 요소의 여러 인스턴스가 필요한 경우 multimap 또는 multiset를 사용하세요. 순서가 지정되지 않은 버전은 unordered_multimapunordered_multiset입니다. 자세한 내용은 클래스, 클래스,unordered_multimapmultiset클래스unordered_multiset 클래스를 참조 multimap 하세요.

순서가 지정된 맵 및 집합은 양방향 반복기를 지원하고 순서가 지정되지 않은 맵 및 집합은 정방향 반복기를 지원합니다. 자세한 내용은 반복기를 참조하세요.

연관 컨테이너의 유형이 다른 조회(C++14)

순서가 지정된 결합 컨테이너(map, multimap, set 및 multiset)는 이제 다른 유형의 조회를 지원하므로 더 이상 같은 멤버 함수 find() 의 키 또는 요소와 lower_bound()동일한 개체 형식을 전달할 필요가 없습니다. 대신, 오버로드된 operator<가 정의되어 있으며 키 형식 비교가 가능하다면 어떠한 형식도 전달할 수 있습니다.

다른 유형의 조회는 다음과 같이 컨테이너 변수를 선언할 때 "std::greater<>다이아몬드 펀터" 비교자를 지정할 std::less<> 때 옵트인 기준으로 사용하도록 설정됩니다.

std::set<BigObject, std::less<>> myNewSet;

기본 비교 연산자를 사용하는 경우 컨테이너는 C++11 이전의 경우와 똑같이 작동합니다.

다음 예제에서는 각 개체 BigObject::id 의 멤버와 비교할 수 있는 std::set 작은 문자열을 전달하여 조회를 수행할 수 있도록 오버로드 operator< 하는 방법을 보여 줍니다.

#include <set>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

class BigObject
{
public:
    string id;
    explicit BigObject(const string& s) : id(s) {}
    bool operator< (const BigObject& other) const
    {
        return this->id < other.id;
    }

    // Other members....
};

inline bool operator<(const string& otherId, const BigObject& obj)
{
    return otherId < obj.id;
}

inline bool operator<(const BigObject& obj, const string& otherId)
{
    return obj.id < otherId;
}

int main()
{
    // Use C++14 brace-init syntax to invoke BigObject(string).
    // The s suffix invokes string ctor. It is a C++14 user-defined
    // literal defined in <string>
    BigObject b1{ "42F"s };
    BigObject b2{ "52F"s };
    BigObject b3{ "62F"s };
    set<BigObject, less<>> myNewSet; // C++14
    myNewSet.insert(b1);
    myNewSet.insert(b2);
    myNewSet.insert(b3);
    auto it = myNewSet.find(string("62F"));
    if (it != myNewSet.end())
        cout << "myNewSet element = " << it->id << endl;
    else
        cout << "element not found " << endl;

    // Keep console open in debug mode:
    cout << endl << "Press Enter to exit.";
    string s;
    getline(cin, s);
    return 0;
}

//Output: myNewSet element = 62F

다른 유형의 조회를 지원하도록 map, multimap, set 및 multiset의 다음 멤버 함수가 오버로드되었습니다.

  1. find

  2. count

  3. lower_bound

  4. upper_bound

  5. equal_range

컨테이너 어댑터

컨테이너 어댑터는 간단 명료하게 인터페이스를 제한하는 시퀀스 또는 연관 컨테이너의 변형입니다. 컨테이너 어댑터는 반복기를 지원하지 않습니다.

queue 컨테이너는 FIFO(선입 선출) 의미 체계를 따릅니다. 큐에 푸시(삽입)되는 첫 번째 요소가 큐에서 처음으로 (제거)됩니다. 자세한 내용은 클래스를 참조 queue 하세요.

priority_queue 컨테이너는 값이 가장 큰 요소가 항상 큐에서 첫 번째에 위치하도록 구성됩니다. 자세한 내용은 클래스를 참조 priority_queue 하세요.

stack 컨테이너는 LIFO(후입 선출) 의미 체계를 따릅니다. 스택에 푸시된 마지막 요소가 첫 번째 팝되는 요소입니다. 자세한 내용은 클래스를 참조 stack 하세요.

컨테이너 어댑터는 반복기를 지원하지 않으므로 C++ 표준 라이브러리 알고리즘과 함께 사용할 수 없습니다. 자세한 내용은 알고리즘을 참조하세요.

컨테이너 요소에 대한 요구 사항

일반적으로 C++ 표준 라이브러리 컨테이너에 삽입되는 요소는 임의의 개체 형식에 대한 요소입니다(복사할 수 있는 경우). 이동 전용 요소(예: vector<unique_ptr<T>>을 사용하여 만든 unique_ptr<>)는 복사를 시도하는 멤버 함수를 호출하지 않는 한 작동합니다.

소멸자가 예외를 throw할 수 없습니다.

이 문서의 앞부분에서 설명한 순서가 지정된 연관 컨테이너는 공용 비교 연산자를 정의해야 합니다. 기본적으로 연산자는 operator<사용되지 operator< 않는 형식도 지원됩니다.

또한 컨테이너의 일부 작업은 공용 기본 생성자와 해당하는 공용연산자가 필요할 수 있습니다. 예를 들어, 순서가 지정되지 않은 연관 컨테이너는 같음 및 해시를 지원해야 합니다.

컨테이너 요소 액세스

반복기를 사용하여 컨테이너 요소에 액세스합니다. 자세한 내용은 반복기를 참조하세요.

참고 항목

range-based for 루프를 사용하여 C++ 표준 라이브러리 컬렉션을 반복할 수도 있습니다.

컨테이너 비교

모든 컨테이너는 같은 요소 형식을 가진 같은 형식의 두 컨테이너를 비교하기 위해 == 연산자를 오버로드합니다. ==를 사용하여 벡터<문자열을 다른 벡터<문자열>>과 비교할 수 있지만 벡터<문자열과 목록<문자열 또는 벡터 문자열>>>을 벡터<<char*>에 비교하는 데 사용할 수는 없습니다. C++98/03에서는 서로 다른 컨테이너 형식 및/또는 요소 형식을 사용 std::equal 하거나 std::mismatch 비교할 수 있습니다. C++11에서는 을(를) 사용할 std::is_permutation수도 있습니다. 그러나 이러한 모든 경우에서 함수는 컨테이너의 길이가 같다고 가정합니다. 두 번째 범위가 첫 번째 범위보다 짧은 경우 정의되지 않은 동작이 나타납니다. 두 번째 범위가 더 긴 경우에도 첫 번째 범위의 끝 이후에는 비교가 계속되지 않기 때문에 잘못된 결과가 나옵니다.

다른 종류의 컨테이너 비교(C++14)

C++14 이상에서는 두 개의 전체 범위를 사용하는 함수 오버로드 중 std::equalstd::mismatch하나를 사용하여 서로 다른 컨테이너 및/또는 std::is_permutation 다른 요소 형식을 비교할 수 있습니다. 이러한 오버로드를 사용하면 길이가 서로 다른 컨테이너를 비교할 수 있습니다. 이 오버로드는 사용자 오류 취약성이 훨씬 덜하며 길이가 서로 다른 컨테이너를 비교할 때 일정한 시간에 false를 반환하도록 최적화되어 있습니다. 따라서 뚜렷한 이유가 없거나 이중 범위 최적화의 이점을 얻지 못하는 컨테이너를 std::list 사용하지 않는 한 이러한 오버로드를 사용하는 것이 좋습니다.

참고 항목

병렬 컨테이너
<sample container>
C++ 표준 라이브러리의 스레드 보안