c++ 将成员函数作为参数传递给另一个函数?

kqlmhetl  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(106)

我在给机器人编代码找乐子。我想添加一个自动循环,这样机器人就可以遵循一组预设的命令并自行驱动。问题是,机器人的每个子系统都是一个不同的类,我希望能够创建一个类似这样的函数:

DoFunctionForMe(start_time, end_time, function, start_arguments, end_arguments);

我希望DoFunctionForMe做的是在开始时间执行带有start参数的函数,并在结束时间执行end参数。
例如,我可以有以下内容,它将从时间1移动到时间8,并从时间7移动到时间9:

void Robot::AutoMainLoop(){
    DoFunctionForMe(1,8,Drive,{12,12},{0,0});
    DoFunctionForMe(7,9,Move,{1,0},{0,0});
}

这里有一个近似的代码,我到目前为止:

class Drivetrain{
    public:
        Drivetrain();

        void Drive(int forward, int left){
            drive(forward, left); // Drives the robot, more complex than this 
        }
}

class Mechanism{
    public:
        Mechanism();

        void Move(int up, int down){
            move(up, down); // Moves the arm, more complex than this
        }
}

class Robot{
    public:
        void DrivenMainLoop(); // Operated by a person

        void AutoMainLoop(); // Robot operates itself

    private:
        Drivetrain m_drivetrain{}; 

        Mechanism m_mechanism{};

}

void Robot::DrivenMainLoop(){
    m_drivetrain.Drive(2,12);

    m_mechanism.Move(1,0);

}

void Robot::AutoMainLoop(){
    // help
}

有什么办法可以让我这么做吗?
我试过使用指向函数的指针,但我真的不明白我在那里做什么,它给了我像a pointer to a bound function may only be used to call the function这样的错误

bkhjykvo

bkhjykvo1#

DriveMove方法是不同类的非静态成员。你必须使用std::bind() + std::function,或者lambda,以便DoFunctionForMe()在不知道它们来自哪个对象的情况下调用它们,例如:

class Drivetrain {
    public:
        ...

        void Drive(int forward, int left) {
            ...
        }
};

class Mechanism {
    public:
        ...

        void Move(int up, int down) {
            ...
        }
};

class Robot {
    public:
        ...

        void AutoMainLoop(); // Robot operates itself

    private:
        Drivetrain m_drivetrain{}; 

        Mechanism m_mechanism{};
};

...

void DoFunctionForMe(..., std::function<void(int,int)> the_function, ...) {
    ...
    the_function(arg1, arg2);
    ...
}

/* or:

template<typename Callable>
void DoFunctionForMe(..., Callable the_function, ...) {
    ...
    the_function(arg1, arg2);
    ...
}
*/

void Robot::AutoMainLoop() {
    using namespace std::placeholders;

    auto drive = std::bind(&Drivetrain::Drive, &m_drivetrain, _1, _2);
    DoFunctionForMe(..., drive, ...);

    auto move = std::bind(&Mechanism::Move, &m_mechanism, _1, _2);
    DoFunctionForMe(..., move, ...);

    // or:

    DoFunctionForMe(..., [&](int arg1, int arg2){ m_drivetrain.Drive(arg1, arg2); }, ...);
    DoFunctionForMe(..., [&](int arg1, int arg2){ m_mechanism.Move(arg1, arg2); }, ...);
}

或者,你可以让DrivetrainMechanism继承一个公共基类,这个基类定义了一个virtual方法,它们都覆盖了这个方法,然后你可以让DoFunctionForMe()通过多态在这个基类上操作,例如:

class Actionable {
    public:
        virtual void DoAction(int arg1, int arg2) = 0;
};

class Drivetrain : public Actionable {
    public:
        ...

        void Drive(int forward, int left) {
            ...
        }

        void DoAction(int arg1, int arg2) override {
            Drive(arg1, arg2);
        }
};

class Mechanism : public Actionable {
    public:
        ...

        void Move(int up, int down) {
            ...
        }

        void DoAction(int arg1, int arg1) override {
            Move(arg1, arg2);
        }
};

class Robot {
    public:
        ...

        void AutoMainLoop(); // Robot operates itself

    private:
        Drivetrain m_drivetrain{}; 

        Mechanism m_mechanism{};
};

...

void DoFunctionForMe(..., Actionable &actionable, ...) {
    ...
    actionable.DoAction(arg1, arg2);
    ...
}

void Robot::AutoMainLoop() {
    DoFunctionForMe(..., m_drivetrain, ...);
    DoFunctionForMe(..., m_mechanism, ...);
}

相关问题