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

Eri*_*c B 7 c++ functor c++11 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){}
}
Run Code Online (Sandbox Code Playgroud)

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

void Screen::init(Player& player){

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

}
Run Code Online (Sandbox Code Playgroud)

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

void Screen::update(){
    foreach (auto control : controls){
        if(...) 
            control.press();
        else if (...) 
            control.release();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 1

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

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

复制时要检查的唯一潜在问题是任何捕获的值是否不存在或本身不可复制。有关此的更多信息,请参见此处

在你的情况下Player仍然存在并且复制参考文献就可以了。

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

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

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

是的。

当我循环访问控件向量时,我应该按值还是按引用访问它们

任何一个。尽管Control是一个很小的类,但我认为没有任何理由不按值访问。