如何安全地向下转换 USTRUCTs

3
Unreal Engine支持通过Cast<T>和自定义实现的dynamic_cast<T*>进行UObject*的向下转换。但是,当向下转换USTRUCT对象时,这两种方法都无法使用。
  1. Cast<T> 方法不支持转换为 UScriptStructs
  2. UE4 编译时没有开启 RTTI(例如,对于 cl.exe 设置了 /GR-),而 UE4 对指向 USTRUCT 的指针使用实现的 dynamic_cast<T*>。因此编译器抛出 C4541(见下面的示例)。

在 UE4.22 中是否有一种使用 UE4 的反射系统来 安全地 向下转换 USTRUCT 的方法(因此当 static_cast<T*> 等不可行时)?

如果没有,那么为什么 UE4 不支持通过其 Cast 函数向下转换 USTRUCT?例如,它们应该被引用或者是与蓝图相关的原因吗?


例如(2),在UE4项目中使用:

#pragma once
#include "CoreMinimal.h"

USTRUCT()
struct MyStructBase
{
    virtual ~MyStructBase() = default;
};

USTRUCT()
struct MyStructDerived : public MyStructBase
{};

void TestFunc()
{
    auto lvalue = MyStructBase{};
    auto lvaluePtr = &lvalue;
    auto o = dynamic_cast<MyStructDerived*>(lvaluePtr); // cl.exe throws C4541
}
3个回答

3
在UE4.22中,是否有使用UE4反射系统安全地下转换USTRUCTs的方法(当静态转换static_cast等不可用时)?
我知道这不是一个理想的解决方案,可能并不适合你的情况,但如果你不想使用裸的static_cast,你可以提供一个模板函数来进行强制转换,并添加一个带有TIsDerivedFromstatic_assert,以获得在转换失败时的编译时错误提示。
template<typename T, typename U>
T* CastStruct(U* base)
{
    static_assert(TIsDerivedFrom<T, U>::IsDerived, "Type T has to be derived from U.");
    return static_cast<T*>(base);
}

为什么UE4的Cast函数不支持USTRUCTs的向下转型?
这是因为在虚幻引擎中,结构体被设计为轻量级实体,因此反射机制(Cast函数所需的)并未为其提供最小形式。
当使用指向USTRUCTs的指针时要格外小心,因为它们不仅不受反射支持,而且垃圾回收器、序列化器和用户界面等也都不支持。处理它们时必须知道自己在做什么。

0
根据虚幻引擎论坛中的帖子,在虚幻引擎中没有适用于UStruct的工作动态转换。我不确定为什么,但似乎指向UStruct类型对象的指针不受虚幻引擎反射系统支持,根据这个帖子
你的选择包括C风格转换和像你提到的静态转换。然而,任何一种选项都不是很安全,除非你知道传递给转换的对象是转换中指定的类型,这时静态转换通常是安全的。
C风格转换:
auto o = (MyStructDerived*) lvaluePtr;

静态转换:

auto o = static_cast<MyStructDerived*>(lvaluePtr);

0

您还可以通过检查结构的类型是否是您要转换的类型的子类,以及您要转换的类型是否是该结构类型的子类来检查结构的安全性。如果两个条件都为真,则它们是相同的类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接