#include <iostream>
#include <functional>
#include <string>
class Driver {
private:
std::function<void()> callback;
public:
void setCallback(std::function<void()> cb) {
callback = cb;
}
void execute() {
if (callback) callback();
}
};
class Motor {
private:
int position = 0;
public:
void step() {
position++;
std::cout << "Position: " << position << std::endl;
}
};
int main() {
Driver driver;
Motor motor;
// We use a lambda to wrap the member function call.
// [&motor] captures the specific motor instance from the stack.
// When the driver calls this lambda, the lambda calls motor.step().
driver.setCallback([&motor]() {
motor.step();
});
int N;
if (!(std::cin >> N)) return 0;
for (int i = 0; i < N; ++i) {
std::string cmd;
std::cin >> cmd;
if (cmd == "TRIG") {
driver.execute();
}
}
return 0;
}Explanation & Logic Summary:
Driver class knows nothing about the Motor class. It just knows how to call a void() function. Furthermore, Motor::step technically has a hidden argument (this), so it doesn't match the signature void().void() signature expected by the Driver, but inside its body, it has access to the motor instance (via capture) and calls the specific method.[&motor] because we want to affect the existing motor object. If we captured by value [motor], the lambda would make a copy of the motor, step the copy's position, and the original motor would stay at 0.Firmware Relevance & Real-World Context:
Servo motor1; Servo motor2;). You can bind motor1 to Timer1 and motor2 to Timer2 using this exact technique.open() method.
Input
2 TRIG TRIG
Expected Output
Position: 1 Position: 2