I have recently been reading a design patterns book written for Java, but I am actually interested in applying the techniques to C++, so I am "translating" the examples from Java to C++. I found out that in Java, it is possible to use a lambda expression as a parameter of a function instead of an object (instance of a class). With my current C++ knowledge, I have not found a way to do something equivalent or similar using C++, I don't even know if that is possible, so I give it a try here.
In Java:
public class Light {
public void on()
{
//whatever
}
public void off()
{
//whatever
}
}
public interface Command {
public virtual void execute();
};
public class RemoteControl {
Command m_command;
public RemoteControl() {}
public void setCommand(Command command)
{
m_command = command;
}
}
According to the book, in Java, given the characteristics of the interface (just one method), it is possible to use a lambda with the signature of the method declared in the interface instead of an "instance" of the interface, eg:
RemoteControl remoteControl;
Light livingRoomLight;
remoteControl.setCommand( ()->{livingRoomLight.on();} );
What can I do in C++ to achieve something similar?
My current C++ code:
class Light
{
public:
Light() {}
void on()
{
//whatever
}
void off()
{
//whatever
}
};
class Command
{
public:
virtual ~Command() = default;
virtual void execute() = 0;
};
class RemoteControl
{
private:
std::shared_ptr<Command> m_command = {nullptr};
public:
RemoteControl() {}
void setCommand(std::shared_ptr<Command> command)
{
m_command = command;
}
};
Is it possible in C++ to use a lambda expression instead of a pointer to a Command instance?
Something like:
std::unique_ptr<RemoteControl> remoteControl = std::make_unique<RemoteControl>();
std::shared_ptr<Light> livingRoomLight = std::make_shared<Light>();
remoteControl->setCommand( [livingRoomLight](){ livingRoomLight->on(); );
or
RemoteControl* remoteControl = new RemoteControl;
Light* livingRoomLight = new Light;
std::function<void()> livingRoomLightOn = [livingRoomLight]() { livingRoomLight->on(); };
remoteControl->setCommand( &livingRoomLightOn );