This is why you don’t re-invent the wheel.
Iterating across a std::map:
for (auto it = m_map.begin(); it != my_map.end(); ++it)
{
// it->first is the key, it->second is the value.
}
Iterating across a TMap:
for (auto it = m_map.begin(); it != my_map.end(); ++it)
{
?????
}
Looking in “Containers/Map.h”:
using PairType = TKeyValuePair<KeyType, ValueType>;
...
using HashTableType = THashTable<KeyType, PairType, HashTraits, AllocatorType, AllocatorArgsType...>;
using ConstIterator = typename HashTableType::template Iterator<true>;
using Iterator = typename HashTableType::template Iterator<false>;
Looking in “Containers/HashTable.h”:
template<class KeyType, class ValueType>
struct TKeyValuePair
{
KeyType _Key;
ValueType _Value;
bool operator==(const KeyType& Key) const { return _Key == Key; }
operator const KeyType&() const { return _Key; }
};
...
template<class KeyType, class KeyValueType, class HashTraits, class AllocatorType, typename... AllocatorArgsType>
class THashTable
...
template <bool bConst>
class Iterator
{
public:
using iterator_category = std::forward_iterator_tag;
using value_type = KeyValueType;
...
template <bool _bConst = bConst>
ULANG_FORCEINLINE std::enable_if_t<!_bConst, pointer> operator->()
{
return _CurrentEntry->_KeyValue;
}
...
SEntry* _CurrentEntry;
...
struct SEntry
{
uint32_t _Hash; // 0 means unused
KeyValueType _KeyValue; // Some value, e.g. index into some external array
};
To put that all together, dereferencing the iterator (operator->) returns _CurrentEntry->_KeyValue which is of type KeyValueType which is actually a TKeyValuePair. So to get the key it should be it→_Key. However when I try that the compiler tells me:
commandlet.cpp:52:96: error: no member named '_Key' in 'TTuple<FString, FString>'
52 | UE_LOG(LogOven, Warning, TEXT("Unexpected command line option '%s' found."), *(it->_Key));
But…but…but…the iterator…the code…where did this ■■■■ TTuple come from?
The official documentation ( Map Containers in Unreal Engine | Unreal Engine 5.5 Documentation | Epic Developer Community ) doesn’t even mention the word “iterator”.
So, when iterating across a TMap, how do I extract the key and value from the iterator?
And why don’t Epic document their stupid custom re-implementations of standard containers properly? Actually I know the answer to that. They are too stupid to realise how stupid their API is and that anyone who doesn’t develop it daily might struggle to use it.