Problem: logging TMap<uint64, TSet> is still nested FString::JoinBy. If the value type later changes from TArray to TSet, every lambda signature has to change with it.
UE_LOG(LogTemp, Display, TEXT("IdToValues: %s"), *FString::JoinBy(IdToValues, TEXT(","), [](const TPair<uint64, TSet<int32>>& Pair) {
return FString::Printf(TEXT("{%llu:[%s]}"), Pair.Key, *FString::JoinBy(Pair.Value, TEXT(","), [](int32 Value) {
return FString::Printf(TEXT("%d"), Value);
}));
}));
Strify is a UE 5.6+ C++ plugin: one call, compile-time overloads (SFINAE / if constexpr).
UE_LOG(LogTemp, Display, TEXT("IdToValues: %s"), *UStrify::ToString(IdToValues, true));
// second arg is Multilines
Not JSON. Not UPROPERTY reflection. Not Blueprint nodes.
LexToString covers scalars; it does not recurse containers or stale weak ptrs.
Add FString ToString() const on a struct or UObject and it is picked up the same way FVector already works.
Limits: UE 5.6+; empty containers stringify to “”; UObject without ToString() renders . Automation specs in the repo.