TMap

TMaps are primarily defined by two types - a key type and a value type - which are stored as associated pairs in the map.

Windows
MacOS
Linux
See Also

After TArray, the most commonly used container in Unreal Engine 4 (UE4) is TMap. TMap is similar to TSet in that its structure is based on hashing keys. However, unlike TSet, this container stores data as key-value pairs (TPair<KeyType, ValueType>), using keys only for storage and retrieval.

There are two types of map: TMap and TMultiMap. The difference between these two is TMap keys are unique, while TMultiMap supports storing multiple, identical keys. When adding a new key-value pair with a key that matches an existing pair to a TMap, the new pair will replace the old one. In a TMultiMap, the container will store both the new pair and the old.

TMap

In a TMap, key-value pairs as the element type of the map as if it was an individual object. In this document, element means a key-value pair, while individual components are referred to as the element's key or the element's value. The element type is actually a TPair<KeyType, ElementType>, though it should be rare to need to refer to the TPair type directly.

Like TArray, TMap is a homogeneous container, meaning that all of its elements are strictly the same type. TMap is also a value type, and supports the usual copying, assignment and destructor operations, as well as strong ownership of its elements, which will be destroyed when the map is destroyed. The key type and value type must also be value types.

TMap is a hashing container which means that the key type must support the GetTypeHash function and provide an operator== for comparing keys for equality. Hashing is covered in more detail later.

TMap can also take an optional allocator to control the memory allocation behavior. However, unlike TArray, these are set allocators rather than the standard UE4 allocators like FHeapAllocator and TInlineAllocator. Set allocators, (class TSetAllocator), define how many hash buckets the map should use and which standard UE4 allocators should be used for hash and element storage.

The final TMap template parameter is KeyFuncs, which tells the map how to retrieve the key from the element type, how to compare two keys for equality and how to hash the key. These have defaults which will just return a reference to the key, use operator== for equality, and call the non-member GetTypeHash function for hashing. If your key type supports these functions, you can use it as a map key without supplying a custom KeyFuncs.

Unlike TArray, the relative order of TMap elements in memory is not reliable or stable, and iterating over the elements is likely to return them in a different order from the order in which they were added. Elements are also unlikely to be laid out contiguously in memory. The backing data structure of a map is a sparse array, which is an array that efficiently supports gaps between its elements. As elements are removed from the map, gaps in the sparse array will appear. Adding new elements into the array can then fill these gaps. However, even though TMap doesn't shuffle elements to fill gaps, pointers to map elements may still be invalidated, as the entire storage can be reallocated when it is full and new elements are added.

Creating and filling a map

You can create a TMap like this:

TMap<int32, FString> FruitMap;

FruitMap is now an empty TMap of strings that are identified by integer keys. We have specified neither an allocator nor a KeyFuncs, so the map will do standard heap allocation and compare the key (of type int32) using operator== and hash it using GetTypeHash. No memory has been allocated at this point.

The standard way to populate a map is to call the Add function with a key and a value:

FruitMap.Add(5, TEXT("Banana"));
FruitMap.Add(2, TEXT("Grapefruit"));
FruitMap.Add(7, TEXT("Pineapple"));
// FruitMap == [
//  { Key: 5, Value: "Banana"     },
//  { Key: 2, Value: "Grapefruit" },
//  { Key: 7, Value: "Pineapple"  }
// ]

While the elements are listed here in the order of insertion, there is no guarantee as to their actual order in memory. For a new map, they are likely to be in order of insertion, but as more insertions and removals happen, it becomes increasingly unlikely that new elements will appear at the end.

This is not a TMultiMap, so keys are guaranteed to be unique. The following is the result of attempting to add a duplicate key:

FruitMap.Add(2, TEXT("Pear"));
// FruitMap == [
//  { Key: 5, Value: "Banana"    },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" }
// ]

The map still contains three elements, but the previous "Grapefruit" value with a key of 2 has been replaced with "Pear".

The Add function can accept a key without a value. When this overloaded Add is called, the value will be default-constructed:

FruitMap.Add(4);
// FruitMap == [
//  { Key: 5, Value: "Banana"    },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: ""          }
// ]

Like TArray, we can also use Emplace instead of Add to avoid the creation of temporaries when inserting into the map:

FruitMap.Emplace(3, TEXT("Orange"));
// FruitMap == [
//  { Key: 5, Value: "Banana"    },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: ""          },
//  { Key: 3, Value: "Orange"    }
// ]

Here, the key and value are passed directly to their respective type constructors. While this isn't meaningful for the int32 key, it does avoid the creation of a temporary FString for the value. Unlike TArray, it's only possible to emplace elements into a map with single-argument constructors.

You can also merge two maps with the Append function, which will move all elements from one map into the other:

TMap<int32, FString> FruitMap2;
FruitMap2.Emplace(4, TEXT("Kiwi"));
FruitMap2.Emplace(9, TEXT("Melon"));
FruitMap2.Emplace(5, TEXT("Mango"));
FruitMap.Append(FruitMap2);
// FruitMap == [
//  { Key: 5, Value: "Mango"     },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: "Kiwi"      },
//  { Key: 3, Value: "Orange"    },
//  { Key: 9, Value: "Melon"     }
// ]
// FruitMap2 is now empty.

In the above example, the resulting map is equivalent to using Add or Emplace to add each element of FruitMap2 individually, emptying FruitMap2 when the process is complete. This means that any element from FruitMap2 that shares its key with an element already in FruitMap will replace that element.

If you mark the TMap with the UPROPERTY macro and one of the "editable" keywords (EditAnywhere, EditDefaultsOnly, or EditInstanceOnly), you can add and edit elements in the Editor.

UPROPERTY(Category = MapsAndSets, EditAnywhere)
TMap<int32, FString> FruitMap;

Iteration

Iteration over TMaps is similar to TArrays. You can use C++'s ranged-for feature, remembering that the element type is a TPair:

for (auto& Elem : FruitMap)
{
    FPlatformMisc::LocalPrint(
        *FString::Printf(
            TEXT("(%d, \"%s\")\n"),
            Elem.Key,
            *Elem.Value
        )
    );
}
// Output:
// (5, "Mango")
// (2, "Pear")
// (7, "Pineapple")
// (4, "Kiwi")
// (3, "Orange")
// (9, "Melon")

You can also create iterators with the CreateIterator and CreateConstIterators functions. CreateIterator will return an iterator with read-write access, while CreateConstIterator returns a read-only iterator. In either case, you can use the Key and Value functions of these iterators to examine the elements. Printing the contents of our example "fruit" map using iterators would look like this:

for (auto It = FruitMap.CreateConstIterator(); It; ++It)
{
    FPlatformMisc::LocalPrint(
        *FString::Printf(
            TEXT("(%d, \"%s\")\n"),
            It.Key(),   // same as It->Key
            *It.Value() // same as *It->Value
        )
    );
}

Queries

To find out how many elements are currently in the map, call the Num function.

int32 Count = FruitMap.Num();
// Count == 6

In order to determine whether or not a map contains a specific key, call the Contains function, as follows:

bool bHas7 = FruitMap.Contains(7);
bool bHas8 = FruitMap.Contains(8);
// bHas7 == true
// bHas8 == false

If you know that your map contains a certain key, you can look up the corresponding value with operator[], using the key as the index. Doing this with a non-const map will return a non-const reference, while a const map will return a const reference.

You should check that the map contains the key before using operator[]. If the map does not contain the key, it will assert.

FString Val7 = FruitMap[7];
// Val7 == "Pineapple"
FString Val8 = FruitMap[8];
// Assert!

If you are unsure of whether or not your map contains a key, you could check with the Contains function, and then use operator[]. However, this is suboptimal, since a successful retrieval involves two lookups on the same key. The Find function combines these behaviors with only a single lookup. Find returns a pointer to the value of the element if the map contains the key, or a null pointer if it does not. Calling Find on a const map will cause the pointer it returns to be const as well.

FString* Ptr7 = FruitMap.Find(7);
FString* Ptr8 = FruitMap.Find(8);
// *Ptr7 == "Pineapple"
//  Ptr8 == nullptr

Alternately, to ensure that you get a valid result from your query, you can use FindOrAdd or FindRef. FindOrAdd will return a reference to the value associated with the key you provide. If the key was not in the map, FindOrAdd will return a newly-created element, with your key and the default-contructed value, that it will also add to the map. Because it can potentially modify the map, FindOrAdd is only available for non-const maps. FindRef, despite its name, will return a copy of the value associated with your key, or a default-constructed value if your key is not found in the map. FindRef does not create a new element, and thus is available for use with both const and non-const maps. Because FindOrAdd and FindRef succeed even when the key isn't found in the map, you can safely call them without the usual safety procedures like checking Contains in advance, or null-checking the return value.

FString& Ref7 = FruitMap.FindOrAdd(7);
// Ref7     == "Pineapple"
// FruitMap == [
//  { Key: 5, Value: "Mango"     },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: "Kiwi"      },
//  { Key: 3, Value: "Orange"    },
//  { Key: 9, Value: "Melon"     }
// ]
FString& Ref8 = FruitMap.FindOrAdd(8);
// Ref8     == ""
// FruitMap == [
//  { Key: 5, Value: "Mango"     },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: "Kiwi"      },
//  { Key: 3, Value: "Orange"    },
//  { Key: 9, Value: "Melon"     },
//  { Key: 8, Value: ""          }
// ]

FString Val7 = FruitMap.FindRef(7);
FString Val6 = FruitMap.FindRef(6);
// Val7     == "Pineapple"
// Val6     == ""
// FruitMap == [
//  { Key: 5, Value: "Mango"     },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: "Kiwi"      },
//  { Key: 3, Value: "Orange"    },
//  { Key: 9, Value: "Melon"     },
//  { Key: 8, Value: ""          }
// ]

Because FindOrAdd can add new entries to the map, as it does when initializing Ref8 in our example, previously-obtained pointers (from Find) or references (from FindOrAdd) could become invalid. This is a result of the addition operation allocating memory and moving existing data if the map's backend storage needs to expand to contain the new element. In the example above, Ref7 may be invalidated after Ref8 after the call to FindOrAdd(8).

The FindKey function performs a reverse lookup, meaning that a supplied value is matched to a key, and returns a pointer to the first key that's paired to the provided value. Searches for a value that isn't present in the map will return a null key.

const int32* KeyMangoPtr   = FruitMap.FindKey(TEXT("Mango"));
const int32* KeyKumquatPtr = FruitMap.FindKey(TEXT("Kumquat"));
// *KeyMangoPtr   == 5
//  KeyKumquatPtr == nullptr

Lookups by value are slower (linear time) than lookups by key. This is because the map is sorted by key, not by value. In addition, if a map has multiple keys with the same value, FindKey may return any of them.

The GenerateKeyArray and GenerateValueArray functions populate a TArray with a copy of all the keys and values respectively. In both cases, the array being passed is emptied before population, so the resulting number of elements will always equal the number of elements in the map.

TArray<int32>   FruitKeys;
TArray<FString> FruitValues;
FruitKeys.Add(999);
FruitKeys.Add(123);
FruitMap.GenerateKeyArray  (FruitKeys);
FruitMap.GenerateValueArray(FruitValues);
// FruitKeys   == [ 5,2,7,4,3,9,8 ]
// FruitValues == [ "Mango","Pear","Pineapple","Kiwi","Orange",
//                  "Melon","" ]

Removal

Elements can be removed from maps by using the Remove function and providing the key of the element to remove. The return value is the number of elements that were removed, and can be zero if the map didn't contain any elements matching the key.

FruitMap.Remove(8);
// FruitMap == [
//  { Key: 5, Value: "Mango"     },
//  { Key: 2, Value: "Pear"      },
//  { Key: 7, Value: "Pineapple" },
//  { Key: 4, Value: "Kiwi"      },
//  { Key: 3, Value: "Orange"    },
//  { Key: 9, Value: "Melon"     }
// ]

Removing elements can leave holes in the data structure, which you can see when visualizing the map in Visual Studio's watch window, but they have been omitted here for clarity.

The FindAndRemoveChecked function can be used to remove an element from the map and return its value. The "checked" part of the name indicates that the map will call check (UE4's equivalent of assert) if the key does not exist.

FString Removed7 = FruitMap.FindAndRemoveChecked(7);
// Removed7 == "Pineapple"
// FruitMap == [
//  { Key: 5, Value: "Mango"  },
//  { Key: 2, Value: "Pear"   },
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 3, Value: "Orange" },
//  { Key: 9, Value: "Melon"  }
// ]

FString Removed8 = FruitMap.FindAndRemoveChecked(8);
// Assert!

The RemoveAndCopyValue function is similar to Remove, but copies the value of the removed element out to a reference parameter. If the key you specified is not present in the map, the output parameter will be unchanged and the function will return false.

FString Removed;
bool bFound2 = FruitMap.RemoveAndCopyValue(2, Removed);
// bFound2  == true
// Removed  == "Pear"
// FruitMap == [
//  { Key: 5, Value: "Mango"  },
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 3, Value: "Orange" },
//  { Key: 9, Value: "Melon"  }
// ]
bool bFound8 = FruitMap.RemoveAndCopyValue(8, Removed);
// bFound8  == false
// Removed  == "Pear", i.e. unchanged
// FruitMap == [
//  { Key: 5, Value: "Mango"  },
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 3, Value: "Orange" },
//  { Key: 9, Value: "Melon"  }
// ]

Finally, you can remove all elements from the map with the Empty or Reset functions.

TMap<int32, FString> FruitMapCopy = FruitMap;
// FruitMapCopy == [
//  { Key: 5, Value: "Mango"  },
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 3, Value: "Orange" },
//  { Key: 9, Value: "Melon"  }
// ]

FruitMapCopy.Empty();       // We could also have called Reset() here.
// FruitMapCopy == []

Empty and Reset are similar, but Empty can take a parameter to indicate how much slack to leave in the map, while Reset always leaves as much slack as possible.

Sorting

A TMap can be sorted. After sorting, iteration over the map will present the elements in sorted order, but this behavior is only guaranteed until the next time you modify the map. Sorting is unstable, so equivalent elements in a MultiMap may appear in any order.

You can sort by key or by value using the KeySort or ValueSort functions, respectively. Both functions take a binary predicate which specifies the sort order.

FruitMap.KeySort([](int32 A, int32 B) {
    return A > B; // sort keys in reverse
});
// FruitMap == [
//  { Key: 9, Value: "Melon"  },
//  { Key: 5, Value: "Mango"  },
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 3, Value: "Orange" }
// ]

FruitMap.ValueSort([](const FString& A, const FString& B) {
    return A.Len() < B.Len(); // sort strings by length
});
// FruitMap == [
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 5, Value: "Mango"  },
//  { Key: 9, Value: "Melon"  },
//  { Key: 3, Value: "Orange" }
// ]

Operators

Like TArray, TMap is a regular value type and as such can be copied with the standard copy constructor or assignment operator. Maps strictly own their elements, so copying a map is deep; the new map will have its own copy of the elements.

TMap<int32, FString> NewMap = FruitMap;
NewMap[5] = "Apple";
NewMap.Remove(3);
// FruitMap == [
//  { Key: 4, Value: "Kiwi"   },
//  { Key: 5, Value: "Mango"  },
//  { Key: 9, Value: "Melon"  },
//  { Key: 3, Value: "Orange" }
// ]
// NewMap == [
//  { Key: 4, Value: "Kiwi"  },
//  { Key: 5, Value: "Apple" },
//  { Key: 9, Value: "Melon" }
// ]

TMap supports move semantics, which can be invoked using the MoveTemp function. After a move, the source map is guaranteed to be empty:

FruitMap = MoveTemp(NewMap);
// FruitMap == [
//  { Key: 4, Value: "Kiwi"  },
//  { Key: 5, Value: "Apple" },
//  { Key: 9, Value: "Melon" }
// ]
// NewMap == []

Slack

Slack is allocated memory that doesn't contain an element. You can allocate memory without adding elements by calling Reserve, and you can remove elements without deallocating the memory they were using by calling Reset or by calling Empty with a non-zero slack parameter. Slack optimizes the process of adding new elements to the map by using pre-allocated memory instead of having to allocate new memory. It can also help with element removal, since the system does not need to deallocate memory. This is especially efficient when you are emptying a map that you expect to repopulate immediately with the same number of elements or fewer.

TMap does not provide a way of checking how many elements are preallocated, like the Max function in TArray does.

In this code, the Reserve function preallocates our map to contain up to ten elements.

FruitMap.Reserve(10);
for (int32 i = 0; i < 10; ++i)
{
    FruitMap.Add(i, FString::Printf(TEXT("Fruit%d"), i));
}
// FruitMap == [
//  { Key: 9, Value: "Fruit9" },
//  { Key: 8, Value: "Fruit8" },
//  ...
//  { Key: 1, Value: "Fruit1" },
//  { Key: 0, Value: "Fruit0" }
// ]

To remove all slack from a TMap, use the Collapse and Shrink functions. Shrink removes all slack from the end of the container, but this will leave any empty elements in the middle or at the start.

for (int32 i = 0; i < 10; i += 2)
{
    FruitMap.Remove(i);
}
// FruitMap == [
//  { Key: 9, Value: "Fruit9" },
//  <invalid>,
//  { Key: 7, Value: "Fruit7" },
//  <invalid>,
//  { Key: 5, Value: "Fruit5" },
//  <invalid>,
//  { Key: 3, Value: "Fruit3" },
//  <invalid>,
//  { Key: 1, Value: "Fruit1" },
//  <invalid>
// ]
FruitMap.Shrink();
// FruitMap == [
//  { Key: 9, Value: "Fruit9" },
//  <invalid>,
//  { Key: 7, Value: "Fruit7" },
//  <invalid>,
//  { Key: 5, Value: "Fruit5" },
//  <invalid>,
//  { Key: 3, Value: "Fruit3" },
//  <invalid>,
//  { Key: 1, Value: "Fruit1" }
// ]

Shrink only removed one invalid element in the code above because there was only one empty element at the end. To remove all slack, the Compact function should be called first, so that the empty spaces will be grouped together in preparation for Shrink.

FruitMap.Compact();
// FruitMap == [
//  { Key: 9, Value: "Fruit9" },
//  { Key: 7, Value: "Fruit7" },
//  { Key: 5, Value: "Fruit5" },
//  { Key: 3, Value: "Fruit3" },
//  { Key: 1, Value: "Fruit1" },
//  <invalid>,
//  <invalid>,
//  <invalid>,
//  <invalid>
// ]
FruitMap.Shrink();
// FruitMap == [
//  { Key: 9, Value: "Fruit9" },
//  { Key: 7, Value: "Fruit7" },
//  { Key: 5, Value: "Fruit5" },
//  { Key: 3, Value: "Fruit3" },
//  { Key: 1, Value: "Fruit1" }
// ]

KeyFuncs

As long as a type has an operator== and a non-member GetTypeHash overload, you can use it as a key type for a TMap without any changes. However, you may want to use types as keys without overloading those functions. In these cases, you can provide your own custom KeyFuncs. To create KeyFuncs for your key type, you must define two typedefs and three static functions, as follows:

  • KeyInitType - Type used to pass keys around.

  • ElementInitType - Type used to pass elements around.

  • KeyInitType GetSetKey(ElementInitType Element) - Returns the key of an element.

  • bool Matches(KeyInitType A, KeyInitType B) - Returns true if A and B are equivalent, false otherwise.

  • uint32 GetKeyHash(KeyInitType Key) - Returns the hash value of Key.

KeyInitType and ElementInitType are typedefs to the normal passing convention of the key type and element type. Usually these will be a value for trivial types and a const reference for non-trivial types. Remember that the element type of a map is a TPair.

An example of a custom KeyFuncs might look like this:

struct FMyStruct
{
    // String which identifies our key
    FString UniqueID;

    // Some state which doesn't affect struct identity
    float SomeFloat;

    explicit FMyStruct(float InFloat)
        : UniqueID (FGuid::NewGuid().ToString())
        , SomeFloat(InFloat)
    {
    }
};
template <typename ValueType>
struct TMyStructMapKeyFuncs :
    BaseKeyFuncs<
        TPair<FMyStruct, ValueType>,
        FString
    >
{
private:
    typedef BaseKeyFuncs<
        TPair<FMyStruct, ValueType>,
        FString
    > Super;

public:
    typedef typename Super::ElementInitType ElementInitType;
    typedef typename Super::KeyInitType     KeyInitType;

    static KeyInitType GetSetKey(ElementInitType Element)
    {
        return Element.Key.UniqueID;
    }

    static bool Matches(KeyInitType A, KeyInitType B)
    {
        return A.Compare(B, ESearchCase::CaseSensitive) == 0;
    }

    static uint32 GetKeyHash(KeyInitType Key)
    {
        return FCrc::StrCrc32(*Key);
    }
};

FMyStruct features a unique identifier, as well as some other data that does not contribute to its identity. GetTypeHash and operator== would be inappropriate here, because operator== should not ignore any of the type's data for general-purpose usage, but would simultaneously need to do so in order to be consistent with the behavior of GetTypeHash, which only looks at the UniqueID field. The following steps will help to create a custom KeyFuncs for FMyStruct:

  1. First, inherit BaseKeyFuncs, as it helpfully defines some types, including KeyInitType and ElementInitType.

    BaseKeyFuncs takes two template parameters: the element type of the map, and the type of our key. As with all maps, the element type is a TPair, taking FMyStruct as its KeyType and the template parameter of TMyStructMapKeyFuncsas its ValueType. The replacement KeyFuncs is a template, so that you can specify ValueType on a per-map basis, rather than needing to define a new KeyFuncs every time you want to create a TMap keyed on FMyStruct. The second BaseKeyFuncs argument is the type of the key, not to be confused with the KeyType from TPair, the Key field of the element stores. Since this map should use UniqueID (from FMyStruct) as its key, FString is used here.

  2. Next, define the three required KeyFuncs static functions. The first is GetSetKey, which returns the key for a given element type. Our element type is TPair, and our key is UniqueID, so the function can simply return UniqueID directly.

    The second static function is Matches, which takes the keys of two elements (retrieved by GetSetKey), and compares them to see if they are equivalent. For FString, the standard equivalence test (operator==) is case-insensitive; to replace this with a case-sensitive search, use the Compare function with the appropriate case-comparison option.

  3. Finally, the GetKeyHash static function takes an extracted key and returns a hashed value for it. Because the Matches function is case-sensitive, GetKeyHash must also be. A case-sensitive FCrc function will calculate the hash value from the key string.

  4. Now that the structure supports the behaviors that TMap requires, you can create instances of it.

In this example, we specify the default set allocator. This is because the KeyFuncs parameter is last, and this TMap type requires it.

    TMap<
        FMyStruct,
        int32,
        FDefaultSetAllocator,
        TMyStructMapKeyFuncs<int32>
    > MyMapToInt32;

    // Add some elements
    MyMapToInt32.Add(FMyStruct(3.14f), 5);
    MyMapToInt32.Add(FMyStruct(1.23f), 2);

    // MyMapToInt32 == [
    //  {
    //      Key: {
    //          UniqueID:  "D06AABBA466CAA4EB62D2F97936274E4",
    //          SomeFloat: 3.14f
    //      },
    //      Value: 5
    //  },
    //  {
    //      Key: {
    //          UniqueID:  "0661218447650259FD4E33AD6C9C5DCB",
    //          SomeFloat: 1.23f
    //      },
    //      Value: 5
    //  }
    // ]

When providing your own KeyFuncs, be aware that TMap assumes that two items that compare as equals using Matches will also return the same value from GetKeyHash. In addition, modifying the key of an existing map element in a way which will change the results from either of these functions is considered undefined behavior, as this will invalidate map's internal hash. These rules also apply to the overloads of operator== and GetKeyHash when using the default KeyFuncs.

Miscellaneous

The CountBytes and GetAllocatedSize functions estimate how much memory the internal array is currently utilizing. CountBytes takes an FArchive parameter, while GetAllocatedSize does not. These functions are typically used for stats reporting.

The Dump function takes an FOutputDevice and writes out some implementation information about the contents of the map. This function is usually used for debugging.

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback