8

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

  • Should the std::function's be stored by (const?) reference, or by value, taking into account they capture a reference?
  • Should they be passed to the Control constructor by (const?) reference, or value, (or moved, somehow)?
  • Is it alright to store the Controls by value in a vector this way, or will I need to use an alternative (unique_ptr<Control>, etc.)?
  • when I loop through the controls vector, should I be accessing them by value, or by reference?

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

4

1 回答 1

1

考虑到它们捕获引用,std::functions 应该按(const?)引用还是按值存储?

Lambda 应该按值存储。它们很小,很容易复制。

复制时要检查的唯一潜在问题是任何捕获的值是否不存在或它们本身不可复制。更多信息在这里

在您的情况下Player仍然存在并且复制参考很好。

它们是否应该通过(const?)引用或值(或以某种方式移动)传递给 Control 构造函数?

出于与上述相同的原因,按值传递 lamdas。

以这种方式将控件按值存储在向量中是否可以

是的。

当我遍历控件向量时,我应该通过值还是通过引用来访问它们

任何一个。虽然Control是这么小的班级,但我看不出有任何理由不按价值访问。

于 2018-04-05T20:29:19.033 回答