将 class 中的 lambda 表达式保存为 parameter/variable 到另一个 class

saving a lambda expression as parameter/variable inside a class to another class

我做了一个class和一个结构

class 命名为 Learning,结构命名为 Action

我的Action构造函数有一个参数:对象的函数,函数是std::function<int(int)>.

这是我的 Action 结构:

typedef std::function<int(int)> func;

struct Action {
    // constructor
    Action(func);

    /// methods
    /// operators
    int operator()(int x);

    /// members
    func f;
};

Action(func f) {this->f = f; } 

我的 Action 结构被我的 Learning class 通过调用这个函数使用:

class Learning
{
public:
    void addAction(Action);
    Action getAction(int idx);
private:
    std::vector<Action> actions;
};

void Learning::addAction(Action act)
{
    actions.push_back(act);
}

int Learning::getAction(int idx)
{
   return actions[idx];
}

int main(){
Learning robot;
robot.addAction(Action([](int y) ->int{return y++; }));
std::cout << robot.getAction(0)(0) << std::endl;
return 0;
}

其中 Action 保存在我的 Learning actions 向量中 class:

方法 addAction() 将创建的 Action 对象添加到我的 actions 向量中。另一种方法 'getAction(idx)' 用于从动作向量调用一个动作。

我使用 lambda 表达式作为参数,因为它看起来更干净。

但是当我在 class 中调用 robot.getAction(0)(0)actions[0](0) 时,我得到一个异常:

Unhandled exception at 0x00007FFA4DE44F69 in RL_Q.exe: Microsoft C++ exception: std::bad_function_call at memory location 0x000000C09A7BE4C0.

当我调试它时,在我用给定参数实例化我的 Action 对象后,我的函数 f 是空的。

我该如何解决这个问题?

你来定义

Learning::addAction(Action&) 

以动作参考作为参数。这意味着您必须确保引用对象的生命周期,而不是让它因超出范围而被销毁。但是你在右值

上调用它
// Action(...) immediately goes out of scope
robot.addAction(Action("Up", [](int y) ->int{return y++; }));

因此,您放入向量中的引用都是无效的:它们指向早已消失的对象。如果你想让它工作,你需要拥有它们。这意味着:

class Learning
{  
  public:
    void addAction(Action&&);
  private:
    std::vector<Action> actions;
};

// rvalue reference, so the vector can take ownership of the expiring object
void Learning::addAction(Action&& act)
{
  actions.push_back(std::move(act));
}

您的 addAction 方法需要引用

void addAction(Action&);

然后你用右值调用它

robot.addAction(Action("Up", [](int y) ->int{return y++; }));

您不能将右值绑定到非常量左值引用。使方法成为常量引用或右值引用。

void addAction(const Action&);
void addAction(Action&&);