Search code examples
c++lambdaunreal-engine4

Changing bool on this from inside lambda


I have a bool on a AActor, that I'd like to change from a lambda function, how shall I capture the bool so it is actually changed? I currently use [&], which should pass this by reference as I understand it, however changing the bool from inside the lambda function doesn't change it on the actor.

[&] () { bMyBool = true; };

EDIT 1: more info

bool is defined in the header of the class as protected.

protected:
    UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
    bool bMagBoots;

I have a function to bind a delegate to an input action, that should call the lambda.

void ASPCharacterActor::BindLambdaToAction(UInputComponent* InputComponent, FName ActionName,
EInputEvent InputEventType, TFunctionRef<void()> ActionHandler)
{
    FInputActionHandlerSignature ActionHandlerSignature;
    ActionHandlerSignature.BindLambda(ActionHandler);

    FInputActionBinding ActionBinding = FInputActionBinding(ActionName, InputEventType);
    ActionBinding.ActionDelegate = ActionHandlerSignature;
    InputComponent->AddActionBinding(ActionBinding);
}

Then I call the function inside BeginPlay. The lambda gets called when I press the button, however the bool won't change outside the lambda function. If I print it out inside the lambda it did change, so I think it just gets copied instead of referenced.

void ASPCharacterActor::BeginPlay()
{
    Super::BeginPlay();

    BindLambdaToAction(InputComponent, "MagBoots", IE_Pressed, [&]
    {
        bMagBoots = true;
    });
}

Solution

  • I have no idea what you have done, but your code will do what we expect by using the following environment around your single code line:

    int main()
    {
        bool bMyBool = false;
    
        auto l= [&] () { bMyBool = true; };
        l();
        std::cout << bMyBool << std::endl;
    }
    

    And as in your edit mentioned, you use it in a class context:

    // Same in class context:
    class X
    {
        private:
            bool bMyBool = false;
            std::function<void(void)> lam; 
        public:
    
            void CreateAndStoreLambda() 
            {
                lam= [&] () { bMyBool = true; };
                // or you can capture this to access all vars of the instance like:
                // lam= [this] () { bMyBool = true; };
            }
    
            void CallLambda()
            {
                lam();
                std::cout << bMyBool << std::endl;
            }
    };
    
    int main()
    {
        X x; 
        x.CreateAndStoreLambda();
        x.CallLambda();
    }
    

    see it running