4

I'm currently learning game development with c++ in Unreal Engine and I came across the function that takes a function pointer as an input:

InputHandle->BindAction("Grab",IE_Pressed, this, &UGrabber::Grab);

From basic C++ I know that in passing a function pointer as an attribute (UGrabber::Grab) - & is optional, however UEngine complains with the following error code if I omit the &:

error C3867: 'UGrabber::Grab': non-standard syntax; use '&' to create a pointer to member

Could someone explain why?

BindAction function declaration looks like this:

FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename FInputActionHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr Func )
Eduard Kim
  • 265
  • 4
  • 15
  • Are you confusing the two distinct meanings of `&`? One means "reference" (e.g. `int&` = reference to an int), while the other is address-of operator (e.g. `&UGrabber::Grab` = address of `UGrabber::Grab` function). – Algirdas Preidžius Apr 23 '20 at 11:12
  • 4
    FYI: [SO: Why must I use address-of operator to get a pointer to a member function?](https://stackoverflow.com/q/42150125/7478597). While the address operator (`&`) may be omitted to get the address of a _plain_ function this is not allowed in the case of _non-static member_ functions. (I guess the former is an inheritage of C.) – Scheff's Cat Apr 23 '20 at 11:15
  • No I'm aware of the difference between the two. When used before the variable name in passing the attribute the "&" is supposed to pass the address of the variable. Which is where I'm confused as I know that for a function 'void MainFunc(void (*myFunc)())' when I call 'MainFunc' using & is optional like so - 'MainFunc(myFunc)' OR 'MainFunc(&myFunc)' would both be valid – Eduard Kim Apr 23 '20 at 11:19
  • @Scheff ah perfect, thank you – Eduard Kim Apr 23 '20 at 11:20

1 Answers1

2

The BindAction function makes use of a Dynamic Multicast Delegate.

They are one of Unreal's ways of having callback functions. In this case, they rely not just on calling a function, but calling a specific object's function. This is why you need to bass the third parameter (in this example, the parameter is this).

What it's saying is, when the input action is IE_Pressed, call the UGrabber function Grab on object this (this has to be a UGrabber instance of course). This is why it's a pointer to the method. It actually utilizes Unreal's reflection system to find the method on the object. So the this object needs to be UObject, otherwise you can't call a funciton on an object by name in C++.

For more info on this, search for "unreal delegates" and "unreal reflection" in your search engine of choice. Using them is quite easy, and it's not necessary to understand the reflection system to reliably use them. Just don't forget to bind and unbind at the appropriate times.

p.s. You can get quite in depth in this subject of callbacks you want. There are other delegate types that don't rely on reflection, for example non-dynamic delegates, that can bind to lambda functions, and or a more familiar if you're coming from a pure C++ background, where commonly a void* opaque is used, expected to be cast to the needed class pointer.

goose_lake
  • 847
  • 2
  • 15