【问题标题】:When I should define operations-type-traits for a USTRUCT当我应该为 USTRUCT 定义操作类型特征时
【发布时间】:2019-04-13 05:01:21
【问题描述】:

对于虚幻引擎中的某些USTRUCT structs,定义了类型特征TStructOpsTypeTraits<T>。这些提供了关于struct T 已实现功能的布尔列表(封装在枚举中)。

  1. 这些特征有什么用?
  2. 我什么时候应该在我的项目中为我的自定义 USTRUCTs 定义这些特征?

*引擎内的使用示例:

struct TStructOpsTypeTraitsBase2
{
    enum
    {
        WithZeroConstructor            = false,                         // struct can be constructed as a valid object by filling its memory footprint with zeroes.
        WithNoInitConstructor          = false,                         // struct has a constructor which takes an EForceInit parameter which will force the constructor to perform initialization, where the default constructor performs 'uninitialization'.
        WithNoDestructor               = false,                         // struct will not have its destructor called when it is destroyed.
        WithCopy                       = !TIsPODType<CPPSTRUCT>::Value, // struct can be copied via its copy assignment operator.
        // ...
    }
}

像这样使用

template<>
struct TStructOpsTypeTraits<FGameplayEffectContextHandle> : public TStructOpsTypeTraitsBase2<FGameplayEffectContextHandle>
{
    enum
    {
        WithCopy = true,        // Necessary so that TSharedPtr<FGameplayEffectContext> Data is copied around
        WithNetSerializer = true,
        WithIdenticalViaEquality = true,
    };
};

似乎特征用于蓝图中使用的USTRUCTs;并且它们是具有NetSerialize() 函数的结构所必需的。我做了抽查:

  • WithIdenticalViaEquality -> UScriptStruct::HasIdentical() -> EStructFlags::STRUCT_IdenticalNative 仅在用于蓝图的 ::IdenticalHelper() 中使用
  • EStructFlags::STRUCT_NetSerializeNative 用于错误消息(当在蓝图中使用结构时)以及在 FObjectReplicatorFRepLayout 中,自定义属性复制需要存在此特征
  • TStructOpsTypeTraitsBase2 的描述似乎表明,这些特征仅在蓝图中使用 USTRUCTs 时才重要

    类型特征以涵盖脚本结构的自定义方面

UnrealEngine 还为其容器类定义了许多专门的特征(例如TTypeTraitsBase)。与 c++ type_traits 进行比较可能是有意义的。

【问题讨论】:

    标签: unreal-engine4


    【解决方案1】:

    虚幻引擎 4 中“开箱即用”的许多可用功能(例如复制、初始化、序列化等)依赖于每个类的特定信息。这允许不同的类 - 例如 - 自定义如何序列化自己的数据。

    对于从基类UObject 继承的类,所有需要的信息都存储在属性中或由可覆盖的方法返回。例如,如果你想自定义你的 UObject 派生类如何管理序列化,你可以简单地重写它的虚拟 Serialize() 方法。这足以让 UE4 在需要序列化您的类的实例时调用您的自定义实现。

    UE4 中结构的问题在于它们没有继承自一个通用的基类/接口。所以 UE4 没有任何预先声明的属性或方法可以调用。尝试调用未声明的方法当然会导致 C++ 中的编译错误。按照前面关于自定义序列化的示例 - UE4 通常不能在结构上调用 Serialize() 方法,因为它们中的一些/大多数不会有这样的方法,编译器会将其报告为错误。

    TStructOpsTypeTraitsBase2是上述问题的解决方案。您为您的自定义结构声明它的特化,以通知 UE4 哪些方法可用。完成后,使用模板元编程和自动生成代码的混合,UE4 将能够调用这些方法再次提供开箱即用的服务或允许您自定义默认行为。例如,声明 WithSerializer = true 是在通知 UE4 您的结构具有自定义的 Serialize() 方法,因此 UE4 将能够在每次需要序列化您的结构实例时自动调用它。

    TStructOpsTypeTraitsBase2 不仅限于与蓝图一起使用的结构,还可以与 C++ 中使用的USTRUCT() 一起使用。

    when 使用它时,当 UE4 在您的结构上的默认行为不是您想要的(例如,您想在一种不同的方式,而默认实现使用“标准”格式序列化所有非瞬态UPROPERTY()

    虽然“形式”相似,但 TStructOpsTypeTraitsBase2 的范围不同于 C++ type_traits:编译器使用 type_traits 来告知程序/程序员有关平台特性的信息。程序员使用TStructOpsTypeTraitsBase2 通知 UE4 自定义结构的可用“额外”功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 2014-10-07
      • 1970-01-01
      • 2019-11-14
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多