관리 메뉴

기억을 위한 기록들

[UE4-CPP] TMap에 관하여 본문

UnrealEngine/UE4 - CPP

[UE4-CPP] TMap에 관하여

에드윈H 2021. 11. 9. 14:45

TMap이란?

- 키(key)와 값(value)을 짝으로 데이터를 저장.

- 키를 검색하여 값을 얻을 수 있다.

 

 

Add함수

map에 추가하기는 Add함수와 key,value를 이어서 입력해준다.

Add는 키의 고유성을 보장하고, 중복된 키로 입력하게 되면 value만 변경된다.

실수해서 Add뒤에 key만 입력했다면 value는 자료형에 맞는 기본값으로 설정된다.

 

Append 함수

해당 함수를 이용하면 다른맵에서 모든 엘리먼트를 삽입시켜 병합하는 것 역시도 가능. 기존 맵에 같은 key가 있다면 value가 대체된다.

 

 

언리얼 매크로

TMap 에 UPROPERTY 매크로와 편집가능 키워드 (EditAnywhere, EditDefaultsOnly, EditInstanceOnly) 중 하나를 마킹하면, 언리얼 에디터에서 엘리먼트를 추가 및 편집 가능합니다.

 

 

반복 처리

반복처리는 TArray와 유사하고, 엘리먼트 유형이 TPair이다.

추가로, CreateIterator 및 CreateConstIterators 함수로 이터레이터를 만들 수도 있습니다. 

CreateIterator 는 읽기-쓰기 가능한 이터레이터를 반환하는 반면,

CreateConstIterator 는 읽기-전용 이터레이터를 반환합니다.

어느 경우든, 이 이터레이터의 Key 및 Value 함수를 사용해서 엘리먼트를 조사할 수 있습니다. 다음은 이터레이터를 사용해서 예제 "fruit" 맵의 내용을 출력한 것입니다:

 

 

 

쿼리(Map의 정보요청)

 

엘리먼트 개수
특정 키의 여부

 

key로 value 접근
포인터로 받기 없다면 nullptr

결과 유효성을 보장하려면 FindOrAdd 또는 FindRef 를 사용하면 된다. 

 

FindOrAdd 는 제공한 키에 연관된 값으로의 레퍼런스를 반환한다.

키가 맵에 있지 않은 경우, FindOrAdd 는 새로 생성된 엘리먼트에 키와 기본 생성된 값을 반환하고, 맵에 추가한다.

이게 맵을 수정할 수도 있기 때문에, FindOrAdd 는 non-const 맵에만 사용할 수 있다.

 

 FindRef 는 그 이름과 달리 키에 연관된 값, 맵에 그 키가 없는 경우 기본 생성된 값 사본을 반환합니다. FindRef 는 새 엘리먼트를 생성하지 않으므로, const 및 non-const 맵 양쪽에서 사용 가능합니다. 

 

FindOrAdd 및 FindRef 는 맵에서 키를 찾지 못해도 성공하므로, 미리 Contains 검사나 반환 값의 null 검사와 같은 통상의 안전 확인 절차 없이 호출해도 안전합니다.

 

FindKey: 반대로 key값을 조회 할수도 있다. 마찬가지로 포인터형식으로 받아서 해당 키가 없다면 nullptr을 반환한다.

 

* 값 조회는 키 조회보다 (선형 시간으로) 느리다. 맵의 소팅 기준은 value가 아니라 key이기 때문입니다. 게다가 맵에 값이 같은 key가 여럿인 경우, FindKey 가 뭘 반환할지는 알 수 없습니다.

 

 

 

GenerateKeyArray / GenerateValueArray : TArray 를 각각 키 / 값 사본으로 다 채운다.

전달되는 배열은 채우기 전에 전부 비워지므로, 배열 엘리먼트 최종 수는 맵의 엘리먼트 수와 항상 같다.

 

제거

 

Remove : key로 엘리먼트제거 반환값은 제거된 엘리먼트 갯수

키값으로 key value 둘다 제거

 

FindAndRemoveChecked : key로 엘리먼트 제거하면서 제거된 value값 반환. 이름이 checked이 있는것은 언리얼에서 해당되는 assert 확인을 하는것이다.

제거 후 어떤 value가 지워지는지 반환되어 확인 가능

RemoveAndCopyValue : Remove 와 비슷하지만, 제거된 엘리먼트 값을 레퍼런스 파라미터(2번째 변수)로 복사합니다. 지정한 키가 맵에 존재하지 않으면, 출력 파라미터는 바뀌지 않고 함수는 false 를 반환합니다.

- RemoveAndCopyValue(targetKey, ReferenceParam)

Reset/Empty : Empty 또는 Reset 함수로 맵에서 모든 엘리먼트를 제거할 수 있다.

 

 

 

Sorting(정렬)

TMap 은 소팅이 가능하다. 소팅 이후 맵을 반복처리하면 엘리먼트가 소팅된 순서대로 나오지만, 이 순서는 맵을 수정하면 보장되지 않는다. 소팅은 불안정하므로, MultiMap 의 엘리먼트가 어떤 순서로 나올지는 알 수 없습니다.

 

 

 

연산자

TArray 처럼 TMap 은 정규 값 유형이므로, 표준 복사 생성자나 할당 연산자를 통해 복사 가능.

맵은 자신의 엘리먼트를 엄격히 소유하므로, 맵을 복사하면 깊은복사(deep)하여, 새로운 맵(NewMap)은 FruitMap와 별도의 엘리먼트 사본을 갖게 됩니다.

ex 대입연산자 예시

FruitMap의 5는 여전히 Mango이고, 3도 제거되지 않았다.

MoveTemp : TMap 은 MoveTemp 함수 사용시 호출 가능한 이동 시맨틱(move semantic) 역시도 지원합니다. 이동 이후 소스 맵은 빈 상태가 보장됩니다:

 

슬랙(Slack)

Slack (여유분, 슬랙)은 할당된 메모리에 엘리먼트가 없는 것을 말한다. 엘리먼트 없이 메모리를 할당하려면 Reserve 를 호출하면 되고, 메모리 할당을 해제하지(deallocate) 않고 엘리먼트를 제거하는 것도 Reset 호출 또는 Empty 에 0 이 아닌 슬랙 파라미터로 호출하면 된다.

메모리 할당 해제할 필요가 없으니 엘리먼트 제거에도 도움이 된다. 특히 맵을 비우고 엘리먼트 수가 같거나 적은 맵으로 바로 다시 채우려는 경우 특히 효율적이다.

 

Reserve : 엘리먼트 수를 몇개를 할당할지 미리 정한다.

 

 

Shrink/Collapse  : 컨테이너 끝의 모든 슬랙을 제거하지만, 중간이나 시작 부분의 빈 엘리먼트는 남겨 둡니다.

 

 

Compact : 위 코드에서 Shrink 가 제거한 유효하지 않은 엘리먼트가 맨끝에 한개만 있어서, 한개만 제거 하게 되었다.(사이사이 제외) 모든 슬랙을 제거하려면, Compact 함수를 먼저 호출해서 빈 공간을 그룹으로 묶어 Shrink 준비하면 됩니다.