언리얼 C++ 프로그래밍

[언리얼 C++] 컨테이너 클래스 TArray 사용법 (엘리먼트 제거, 연산자)

언린이 2021. 7. 7. 21:50

TArray 컨테이너 클래스의 기본적인 설명과 간단한 사용법은 [언리얼 C++] 컨테이너 클래스 TArray 사용법 (생성 및 삽입, 반복처리) (tistory.com) 글을 참고하시기 바랍니다.

이 글에서는 TArray 컨테이너 클래스의 엘리먼트 제거, 연산자에 대해 알아보겠습니다.

 

 

1. TArray 컨테이너 엘리먼트 제거 기능

TArray<int32> ValArr;
int32 Temp[] = { 10, 20, 30, 5, 10, 15, 20, 25, 30 };
ValArr.Append(Temp, ARRAY_COUNT(Temp));
// ValArr = {10,20,30,5,10,15,20,25,30}

ValArr.Remove(20); // ValArr = {10,30,5,10,15,25,30}

위 예제 코드에서 사용한 Remove() 함수를 통해 컨테이너의 엘리먼트를 제거할 수 있습니다.

Remove() 함수는 엘리먼트 타입의 operator==에 따라, 제공한 파라미터와 동일한 것으로 간주되는 엘리먼트를 모두 제거합니다.

 

ValArr.RemoveSingle(30); // ValArr = {10,5,10,15,25,30}

RemoveSingle() 함수는 Remove() 함수와 동일하게 제공한 파라미터와 동일한 것으로 간주되는 엘리먼트를 제거합니다.

하지만 Remove() 함수처럼 해당하는 모든 엘리먼트들을 제거하는 것이 아니라 0번째 인덱스부터 엘리먼트를 찾아 첫번째에 위치한 엘리먼트만을 제거합니다.

그러므로 컨테이너에 중복된 것이 있는데 하나만 지우고자 한다거나, 컨테이너에 해당 엘리먼트가 딱 하나만 존재하는 것이 확실한 경우 최적화 차원에서도 유용할 수 있습니다.

 

ValArr.RemoveAt(2); // 인덱스 2 엘리먼트를 제거합니다
					// ValArr = {10,5,15,25,30}

ValArr.RemoveAt(99); // 런타임 오류가 발생합니다
                     // 인덱스 99 에 엘리먼트가 없기 때문입니다

RemoveAt() 함수에 인덱스 번호를 넘겨 해당 인덱스에 위치한 엘리먼트를 제거할 수 있습니다.

RemoveAt() 함수로 엘리먼트를 제거하기 전에, IsValidIndex() 함수로 컨테이너에 제공하려는 인덱스가 존재하는지 확인하는 것이 좋습니다. 왜냐하면 RemoveAt() 함수에 유효하지 않은 인덱스를 전달하면 런타임 오류가 발생하기 때문입니다.

 

ValArr.RemoveAll([](int32 Val) {
    return Val % 3 == 0;
}); // ValArr = (10,5,25)

또한, RemoveAll() 함수로 모든 엘리먼트를 제거할 수도 있고, 위 예제 코드처럼 술부를 파라미터로 넘겨 술부에 일치하는 모든 엘리먼트를 제거할 수도 있습니다. 위 예제는 컨테이너 안의 3의 배수인 값을 전부 제거한 것입니다.

 

ValArr.Empty(); // ValArr = {}

마지막으로, Empty() 함수를 사용하여 컨테이너의 모든 엘리먼트들을 제거할 수 있습니다.

 

 

2. TArray 컨테이너 연산자

TArray<int32> ValArr;
ValArr.Add(1);
ValArr.Add(2);
ValArr.Add(3);

auto ValArr2 = ValArr; // ValArr2 = {1,2,3}

ValArr2[0] = 5; // ValArr = {1,2,3}
				// ValArr2 = {5,2,3}

TArray 컨테이너는 일반적인 값 타입으로, 일반적인 생성자 복사나 할당 연산자를 통해 복사할 수 있습니다. 컨테이너는 엘리먼트들을 엄격히 소유하기 때문에, 컨테이너를 새로운 컨테이너에 복사하면 새로운 컨테이너에는 자체적인 엘리먼트 사본들이 생성됩니다.

 

ValArr2 += ValArr; // ValArr2 = {5,2,3,1,2,3}

그리고 Append() 함수의 대안으로, operator+=을 사용하여 컨테이너를 연결시킬 수 있습니다.

 

ValArr = MoveTemp(ValArr2);
// ValArr = {5,2,3,1,2,3}
// ValArr2 = {}

또한, TArray 컨테이너 클래스에는 MoveTemp() 함수가 존재하는데, 해당 함수를 사용하여 컨테이너의 엘리먼트 값들을 다른 컨테이너로 이동시킬 수 있습니다. 이동 이후에 원본 컨테이너는 공백으로 남습니다.

 

TArray<FString> FlavorArr1;
FlavorArr1.Emplace(TEXT("Chocolate"));
FlavorArr1.Emplace(TEXT("Vanilla"));
// FlavorArr1 = {"Chocolate","Vanilla"}

auto FlavorArr2 = FlavorArr1;
// FlavorArr2 = {"Chocolate","Vanilla"}

bool bComparison1 = (FlavorArr1 == FlavorArr2);
// bComparison1 = true

for (auto& Str : FlavorArr2)
{
    Str = Str.ToUpper();
}
// FlavorArr2 = {"CHOCOLATE","VANILLA"}

bool bComparison2 = (FlavorArr1 == FlavorArr2);
// bComparison2 = true, because FString comparison ignores case

Exchange(FlavorArr2[0], FlavorArr2[1]);
// FlavorArr2 = {"VANILLA","CHOCOLATE"}

bool bComparison3 = (FlavorArr1 == FlavorArr2);
// bComparison3 = false, because the order has changed

마지막으로, 컨테이너는 operator==이나 operator!=을 사용하여 비교할 수 있습니다.

두 컨테이너가 동등하다고 판단되는 경우는 엘리먼트의 수, 값 그리고 순서가 같을 경우만입니다.

위 예제 코드를 보시면 엘리먼트의 대소문자는 구분하지 않는다는 것을 알 수 있습니다.