UE中有2种比较有趣的数据结构TGuardValue与TInlineComponentArray,TGuardValue可以让变量离开作用域时恢复原始值,而在作用域中可以任意修改。TInlineComponentArray可以在栈中更高效的分配数组(因为TArray存在一些非栈的额外分配)。
1.TGuardValue
以下为测试代码:
cpp
UE_LOG(LogTemplateCharacter, Warning, TEXT("========== TGuardValue Demo =========="));
int32 Value = 100;
UE_LOG(LogTemplateCharacter, Warning, TEXT("[TGuardValue] Before scope: Value = %d"), Value);
//打印Value = 100
{
// 一般修改值在构造函数里直接设置
TGuardValue<int32> Guard(Value, 999);
UE_LOG(LogTemplateCharacter, Warning, TEXT("[TGuardValue] Inside scope: Value = %d (temporarily overridden)"), Value);
Value = 42;//即使被 TGuardValue '保护',变量依然可以被随意修改,Guard 只负责在最后复原,不负责阻止修改。
UE_LOG(LogTemplateCharacter, Warning, TEXT("[TGuardValue] Inside scope: Value = %d (modified again while guarded)"), Value);
} // 在C++里,花括号可以算作作用域,出了作用域值恢复
UE_LOG(LogTemplateCharacter, Warning, TEXT("[TGuardValue] After scope: Value = %d (restored to original)"), Value);
//打印Value = 100
可以发现,出了花括号作用域数值恢复,运行时截图测试:

在UE的Lyra项目中,也使用到了该数据结构。
2.TInlineComponentArray
我们知道C++如果不声明为指针,默认是在栈上分配的。但因为TArray本身构造函数中存在一些非栈的初始化逻辑代码,因此对于需要在栈上分配的数组使用TInlineComponentArray效率会更高。
测试代码,使用指针遍历成员:
cpp
TInlineComponentArray<UActorComponent*> InlineComponents(this);
UE_LOG(LogTemplateCharacter, Warning,
TEXT("[TInlineComponentArray] Collected %d components from '%s' (inline capacity default = %d)"),
InlineComponents.Num(),
*GetName(),
NumInlinedActorComponents);
for (int32 Index = 0; Index < InlineComponents.Num(); ++Index)
{
UActorComponent* Component = InlineComponents[Index];
UE_LOG(LogTemplateCharacter, Warning,
TEXT("[TInlineComponentArray] [%d] %s (%s)"),
Index,
*GetNameSafe(Component),
Component ? *Component->GetClass()->GetName() : TEXT("null"));
}
运行时测试下:

https://dev.epicgames.com/documentation/unreal-engine/API/Runtime/Core/TGuardValue
https://dev.epicgames.com/documentation/unreal-engine/API/Runtime/Engine/TInlineComponentArray