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 );