Eric B
Eric B

Reputation: 4437

Store and passing std::function's - by value or by reference?

I'm having trouble knowing when to pass/store std::function objects by value or reference, or if I need to use move semantics somehow. I have a struct that stores two std::function objects:

struct Control{
    char key;
    std::function<void()> press;
    std::function<void()> release;
    Control(char key, std::function<void()> press, std::function<void()> release):
        key(key),press(press),release(release){}
}

I also have a class that contains a vector of these structs, and I'd like to initialize it in a function resembling this one:

void Screen::init(Player& player){

    this->controls.push_back(Control(
        'W',
        [&player](){player.go(UP);},
        [&player](){player.stop(UP);}));

}

I'd like to be able to pass lambda expressions directly to the Control constructor, and eventually do this repeatedly:

void Screen::update(){
    foreach (auto control : controls){
        if(...) 
            control.press();
        else if (...) 
            control.release();
    }
}

I've encountered a lot of errors and crashes trying to implement this idea, so I need to know

Assume that the Player& object is always in scope for Screen::update().

Upvotes: 8

Views: 7074

Answers (1)

user9478968
user9478968

Reputation:

Should the std::functions be stored by (const?) reference, or by value, taking into account they capture a reference?

Lambdas should be stored by value. They are small and easily copied.

The only potential issue to check for when copying is if any of the captured values will not exists or are not themselves copy-able. More info on this here.

In your case Player will still be around and copying a reference is fine.

Should they be passed to the Control constructor by (const?) reference, or value, (or moved, somehow)?

Pass lamdas by value for the same reasons as above.

Is it alright to store the Controls by value in a vector this way

Yes.

When I loop through the controls vector, should I be accessing them by value, or by reference

Either. Although Control is such a small class I don't see any reason not to access by value.

Upvotes: 1

Related Questions