Check if variable exists in class

Hello there. I’ve been banging my head against the wall with this for some time now and I just cant seem to find a clear solution. I am trying to check whether a variable exists in a class. The check needs to happen inside a template function.

As an example below lets say I have a function that needs to change some value in a T class:


template 
static FORCEINLINE void SetSomeDefaults(T& SomeClass) {
     SomeClass.someVariable = 1;
}

Since the type of class is unknown, what I wanna do is check whether, in the above case, “someVariable” exists in “SomeClass” and then perform whatever modifications i want. Kinda something like the below:


template 
static FORCEINLINE void SetSomeDefaults(T& SomeClass) {
  if (SomeClass.someVariable -> exists) {
       SomeClass.someVariable = 1;
  }
}

I’ve already looked at type traits and SFINAE but I just cant figure out how to actually apply it in this case.

Any advice, guidance or solution is greatly appreciated.
Thank you in advance.

You’re going to want to dig into the reflection system:

You can find the property you want either with FindPropertyByName (UStruct::FindPropertyByName | Unreal Engine Documentation), or by using a TFieldIterator (TFieldIterator | Unreal Engine Documentation).

Both of these methods operate on UStructs, from which UClass is derived.

static FORCEINLINE void SetSomeDefaults(T& SomeClass)
{
    FName VariableName("someVariable");

    //using FindPropertyByName
    UProperty* PropertyByName = SomeClass->FindPropertyByName(VariableName);
    if(PropertyByName != nullptr) {
        //class has the property

    }

    //using TFieldIterator
    for (TFieldIterator<UIntProperty> PropIt(SomeClass); PropIt; ++PropIt)
    {
        UIntProperty* Property = *PropIt;
        if (VariableName == Property->GetFName()) {
            //class has the property

        }

    }

}

Your example used an int so I went with UIntProperty, but you can specify any UProperty type (e.g. UFloatProperty, UObjectProperty, UBoolProperty, etc.) to iterate through just those member types. If you template TFieldIterator with UProperty it will iterate through every property in the object but if you know what type you’re looking for you can save some time.

It looks like you want to adjust the values within the class itself, however, and I don’t think that’s possible. In order to set or get a value you need a reference to the actual object that holds the property. Even if you knew the type of class you were working with, I don’t think you can change the default values of a class during runtime. At best, you can pull the default object (CDO) and see what they are.

If instead you want to change the value of a property within a specific instance, once you’ve verified the property exists and have a reference to the object, if the property is public setting the value is trivial.

if (TargetObject->GetClass()->FindPropertyByName(VariableName)) {
    TargetObject->someVariable = 1;

}

Of course, this relies on the variable being public, if not it’s a bit more complicated but doable. You’ll need to do something like this:

UIntProperty* IntProperty = TargetObject->GetClass()->FindPropertyByName(VariableName);
void* ValuePtr = IntProperty ->ContainerPtrToValuePtr<void>(TargetObject);
Property->SetIntPropertyValue(ValuePtr, 1);
FPropertyChangedEvent PropertyChange(IntProperty , EPropertyChangeType::ValueSet);
TargetObject->PostEditChangeProperty(PropertyChange);

Calling PostEditChangeProperty is important because otherwise the changes won’t actually take effect.

You’ll probably want to also look at UProperty and its variants (https://docs.unrealengine.com/latest/INT/API/Runtime/CoreUObject/UObject/UProperty/index.html)

You might also have luck with FindField (in UnrealType.h) and/or GET_MEMBER_NAME_CHECKED and it’s variants (see AssertionMacros.h).

Ultimately, it depends on what you want to do with the property, but this should get you started.