Why is there no Target pin in pure functions invoked in their own classes?

In other words, when MemberFunc and PureFunc are invoked in their own class, why is the Target pin mandatory/explicit for MemberFunc but optional/implicit for PureFunc?

Quoted from UE documentation:

The main difference is that Pure Functions promise not to modify state or the members of the class in any way, while Impure Functions are free to modify state. Pure Functions are generally used for getter Functions or operators that just output a data value.

It looks like pure functions are member functions decorated with a trailing const in C++. Correct me if I am wrong. Both are actually just member functions. It does not make sense if Target pin is explicit for mutating member functions but implicit for im-mutating ones.

Any directions are welcome! Thank you in advance!

Edit: I just noticed by experiments that pure functions are not the same as member functions decorated with a trailing const. It means that pure function can still be abused to change data members.

Yes, member functions can be pure or non-pure. With pure functions (as the documentation state) being meant to not modify the state (ie - any values) of the class it is called from.

While I probably won’t have a satisfying answer for why they behave differently. What I will point out is that in other classes, they need to have a target because the code needs to know what object is calling the function.

To borrow from C++, this is like typing object->foo from some other object.

Thank you. I know that Target pin is needed or useful when those both functions are invoked from other classes as already shown in the screenshot above.

void OtherClass::DoingSomething
{
   UBullet* bullet = MyFactory::GetBullet();
   bullet->MemberFunc();
   bullet->PureFunc();
}

But from the class UBullet itself, the this (like Target) is implicit.

void UBullet::DoingSomething
{
   MemberFunc(); // this->MemberFunc();
   PureFunc(); // this->PureFunc();
}

There are cases where this is not implicit and must be explicit. As an example

void UBullet::DoingSomething(int x)
{
      x = x; //cannot tell who belongs to what x!
      this->x = x //explicit this allows us to know who owns what
}

This may seem like bad code, but there will be times where you can’t really name a parameter in a different way that is also clear.

I know this violates the idea of pure functions but I feel compelled to add completeness to the discussion.

With the pure function being called within it’s class, we know with certainty who owns the data and the function (it’s honestly a little silly this does not also happen for non-pure functions) outside, we don’t know for sure. Hence the need to explicitly make sure.

Yes. I also know that case in which explicit this is necessary when our formal parameters have the same identifiers as the data members. Prepending conflicting data members with _ (underscore) is another way to avoid having to explicitly call this.

With the pure function being called within it’s class, we know with certainty who owns the data and the function (it’s honestly a little silly this does not also happen for non-pure functions) outside, we don’t know for sure. Hence the need to explicitly make sure.

I have no problem with member (pure or impure) functions called outside their classes. The Target pin must be mandatory or explicit.

I just noticed that PureFunc can also be invoked within its own class with Target pin if we start with Self node.

bp

OK. I think I understood now. I will close this question shortly.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms