存储和传递std :: function - 按值或按引用?

时间:2013-06-07 18:44:31

标签: c++ c++11 functor std-function

我无法知道何时通过值或引用传递/存储std :: function对象,或者我需要以某种方式使用移动语义。我有一个存储两个std::function对象的结构:

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){}
}

我还有一个包含这些结构的向量的类,我想在类似这个结构的函数中初始化它:

void Screen::init(Player& player){

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

}

我希望能够将lambda表达式直接传递给Control构造函数,并最终重复执行:

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

我遇到了很多错误和崩溃试图实现这个想法,所以我需要知道

  • std::function是应该通过(const?)引用还是按值存储,考虑到它们捕获引用?
  • 是否应该通过(const?)引用或值传递给Control构造函数(或以某种方式移动)?
  • 通过这种方式将控件按值存储在矢量中是否可以,或者我是否需要使用替代(unique_ptr<Control>等)?
  • 当我遍历控件向量时,我应该通过值或引用来访问它们吗?

假设Player&对象始终在Screen::update()的范围内。

1 个答案:

答案 0 :(得分:1)

  

std :: functions是否应该通过(const?)引用或值存储,考虑到它们捕获引用?

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

复制时检查的唯一潜在问题是,如果任何捕获的值不存在或者本身不可复制。 More info on this here

在你的情况下,Player仍然存在,复制引用也没问题。

  

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

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

  

将控件按值存储在矢量中是否正常

  

当我遍历控件向量时,我应该通过值还是通过引用

来访问它们

要么。虽然Control是一个如此小的课程,但我认为没有任何理由不按价值获取。