C++ named requirements: AllocatorAwareContainer (since C++11)
AllocatorAwareContainer 는 Container 의 인스턴스를 보유하고, 해당 인스턴스를 모든 멤버 함수에서 메모리 할당 및 해제와 해당 메모리에서 객체 생성 및 소멸(이러한 객체는 컨테이너 요소, 노드 또는 비정렬 컨테이너의 경우 버킷 배열일 수 있음)에 사용하는 Allocator 입니다 , 단 std::basic_string 특수화는 요소의 생성/소멸에 할당자를 사용하지 않음 (C++23부터) .
다음 규칙들이 컨테이너 생성에 적용됩니다:
- AllocatorAwareContainer 의 복사 생성자는 복사되는 컨테이너의 할당자에서 std:: allocator_traits < allocator_type > :: select_on_container_copy_construction 을 호출하여 할당자 인스턴스를 획득합니다.
- 이동 생성자는 이전 컨테이너에 속한 할당자로부터 이동 생성하여 할당자 인스턴스를 획득합니다.
- 다른 모든 생성자는 const allocator_type & 매개변수를 받습니다.
allocator를 교체하는 유일한 방법은 복사 할당, 이동 할당, 그리고 swap입니다:
- 복사 할당 연산자는 std:: allocator_traits < allocator_type > :: propagate_on_container_copy_assignment :: value 가 true 인 경우에만 할당자를 교체합니다.
- 이동 할당 연산자는 std:: allocator_traits < allocator_type > :: propagate_on_container_move_assignment :: value 가 true 인 경우에만 할당자를 교체합니다.
- Swap 연산은 std:: allocator_traits < allocator_type > :: propagate_on_container_swap :: value 가 true 인 경우에만 할당자를 교체합니다. 구체적으로, 비멤버 함수 swap에 대한 비정규화된 호출을 통해 할당자 인스턴스를 교환합니다( Swappable 참조). swap이 할당자를 전파하지 않는 경우, 서로 다른 할당자를 가진 두 컨테이너를 교환하는 것은 정의되지 않은 동작입니다.
-
접근자
get_allocator()는 컨테이너를 생성하는 데 사용되었거나 가장 최근의 할당자 교체 작업으로 설치된 할당자의 복사본을 반환합니다.
유일한 예외는 std:: basic_string < CharT,Traits,Allocator > :: assign 인데, 이것은 할당자(allocator)도 전파할 수 있습니다.
목차 |
요구사항
타입이 다음 조건을 만족하면 AllocatorAwareContainer 를 만족합니다: Container 요구사항을 만족하고, 아래 주어진 타입과 값들에 대해 아래 표의 의미론적 요구사항과 복잡도 요구사항이 충족되는 경우:
| 유형 | 정의 |
X
|
AllocatorAwareContainer 유형 |
T
|
X
의
value_type
|
A
|
X
가 사용하는 할당자 유형
|
| 값 | 정의 |
| a , b |
X
유형의 비상수 좌측값
|
| c | const X 유형의 좌측값 |
| t |
X
유형의 좌측값 또는 상수 우측값
|
| rv |
X
유형의 비상수 우측값
|
| m |
A
유형의 값
|
타입
| 이름 | 유형 | 요구 사항 |
|---|---|---|
| typename X :: allocator_type |
A
|
X::allocator_type::value_type
과
X::value_type
이 동일해야 합니다.
|
문장
| 구문 | 의미 | 복잡도 | |
|---|---|---|---|
|
X u
;
X u = X ( ) ; |
사전 조건 |
A
가
DefaultConstructible
임.
|
상수 |
| 사후 조건 | u. empty ( ) 와 u. get_allocator ( ) == A ( ) 가 모두 true 임. | ||
| X u ( m ) ; | 사후 조건 | u. empty ( ) 와 u. get_allocator ( ) == m 가 모두 true 임. | 상수 |
| X u ( t, m ) ; | 사전 조건 |
T
가
CopyInsertable
임 (
X
에 대해).
|
선형 |
| 사후 조건 | u == t 와 u. get_allocator ( ) == m 가 모두 true 임. | ||
| X u ( rv ) ; | 사후 조건 |
|
상수 |
| X u ( rv, m ) ; | 사전 조건 |
T
가
MoveInsertable
임 (
X
에 대해).
|
|
| 사후 조건 |
|
||
표현식
| 표현식 | 타입 | 의미론 | 복잡도 | |
|---|---|---|---|---|
| c. get_allocator ( ) |
A
|
직접적인 의미론적 요구사항 없음. | 상수 | |
| a = t |
X&
|
사전 조건 |
T
가
CopyInsertable
into
X
이고
CopyAssignable
임.
|
선형 |
| 사후 조건 | a == t 가 true 임. | |||
| a = rv |
X&
|
사전 조건 |
할당자가 이동 할당으로 교체되지 않는 경우 (
위 참조
),
T
가
MoveInsertable
into
X
이고
MoveAssignable
임.
|
선형 |
| 효과 | a 의 모든 기존 요소들이 이동 할당되거나 파괴됨. | |||
| 사후 조건 | a 와 rv 가 동일한 객체를 참조하지 않으면, a 는 할당 전 rv 가 갖고 있던 값과 동일함. | |||
| a. swap ( b ) | void | 효과 | a 와 b 의 내용을 교환함. | 상수 |
참고 사항
AllocatorAwareContainer
는 항상
std::
allocator_traits
<
A
>
::
construct
(
m, p, args
)
를 호출하여
T
타입의 객체를
p
위치에
args
를 사용하여 생성하며, 이때
m
==
get_allocator
(
)
가 성립합니다.
기본적으로
std::allocator
의
construct
는
::
new
(
(
void
*
)
p
)
T
(
args
)
를 호출합니다
(C++20 이전)
std::allocator
는
construct
멤버를 가지지 않으며, 요소를 생성할 때
std::
construct_at
(
p, args
)
가 호출됩니다
(C++20 이후)
, 하지만 특수화된 할당자는 다른 정의를 선택할 수 있습니다.
표준 라이브러리
모든 표준 라이브러리 문자열 타입과 컨테이너들( std::array 와 std:: inplace_vector 제외)은 AllocatorAwareContainer 입니다:
|
문자 시퀀스를 저장하고 조작함
(클래스 템플릿) |
|
|
양방향 큐
(클래스 템플릿) |
|
|
(C++11)
|
단일 연결 리스트
(클래스 템플릿) |
|
이중 연결 리스트
(클래스 템플릿) |
|
|
크기 조정 가능한 연속 배열
(클래스 템플릿) |
|
|
키-값 쌍의 컬렉션, 키로 정렬됨, 키는 고유함
(클래스 템플릿) |
|
|
키-값 쌍의 컬렉션, 키로 정렬됨
(클래스 템플릿) |
|
|
고유 키의 컬렉션, 키로 정렬됨
(클래스 템플릿) |
|
|
키의 컬렉션, 키로 정렬됨
(클래스 템플릿) |
|
|
(C++11)
|
키-값 쌍의 컬렉션, 키로 해시됨, 키는 고유함
(클래스 템플릿) |
|
(C++11)
|
키-값 쌍의 컬렉션, 키로 해시됨
(클래스 템플릿) |
|
(C++11)
|
고유 키의 컬렉션, 키로 해시됨
(클래스 템플릿) |
|
(C++11)
|
키의 컬렉션, 키로 해시됨
(클래스 템플릿) |
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2839 | C++11 | 표준 컨테이너의 자기 이동 할당이 허용되지 않았음 | 허용되지만 결과는 명시되지 않음 |