Reputation: 8758
Unreal Engine supports downcasting of UObject*
via Cast<T>
and via a custom implementation of dynamic_cast<T*>
.
When downcasting USTRUCT
objects, both methods don't work:
Cast<T>
do not support conversions to UScriptStructs
./GR-
is set for cl.exe) and UE4 uses the dynamic_cast<T*>
of the implementation for pointers to USTRUCT
s. Therefore the compiler throws C4541 (see example below).Is there a method in UE4.22 to safely downcast USTRUCT
s using the reflection system of UE4 (so when static_cast<T*>
etc is not an option)?
If not, then why UE4 doesn't support downcasting USTRUCT
s by its Cast functions? E.g. shouldn't they be referenced or are the reasons Blueprint related?
Example for (2), use within an UE4 project:
#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
}
Upvotes: 3
Views: 8232
Reputation: 1
You can also check the safety of a structure cast by checking if the type of the structure is a child of the type you're casting to, and the type you're casting to is a child of the structure type. If both conditions are true they're the same type.
Upvotes: 0
Reputation: 656
Is there a method in UE4.22 to safely downcast USTRUCTs using the reflection system of UE4 (so when static_cast<T*> etc is not an option)?
I know it's not an ideal solution and might not suit your case, but if you don't want to use a bare static_cast
, you could provide a templated function that does the cast and add a static_assert
with TIsDerivedFrom
inside to get a compile time error were the cast to fail.
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);
}
why UE4 doesn't support downcasting
USTRUCTs
by its Cast functions?
That's because structures are supposed to be lightweight entities in Unreal Engine and thus reflection - which is required for Cast
to work - is not provided provided in a minimal form for them.
Be careful when using pointers to USTRUCTs
as they're not only unsupported by reflection, but also garbage collector, serializers, UI etc. You have to know what you're doing when dealing with them.
Upvotes: 3
Reputation: 8229
According to this post in the Unreal forums, there is no working dynamic cast for UStruct
in Unreal. I'm not sure why, but it seems that pointers to objects of type UStruct
are not support by Unreal's reflection system, according to this post.
Your options here include a C-style cast and like you mentioned, a static cast. However, either option isn't that safe, with the exception that static casts are usually safe when you know the object being passed to the cast is of the type specified in the cast.
C-style cast:
auto o = (MyStructDerived*) lvaluePtr;
Static cast:
auto o = static_cast<MyStructDerived*>(lvaluePtr);
Upvotes: 0