Skip to content

Instantly share code, notes, and snippets.

@WillSams
Last active January 16, 2023 12:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WillSams/f2106be46e302445cfce35456a89bd40 to your computer and use it in GitHub Desktop.
Save WillSams/f2106be46e302445cfce35456a89bd40 to your computer and use it in GitHub Desktop.
GoF Command Pattern using C++ Lambdas
#include <iostream>
#include <stack>
#include <functional>
using Receiver = std::function<void(std::function<void()>)>;
class Command {
public:
virtual void setReceiver(Receiver receiver) = 0;
virtual void execute() = 0;
};
class Data1 : public Command {
private:
std::string str1 = "Suzuki";
std::string str2 = "Ichiro";
Receiver receiver;
public:
void setReceiver(Receiver rec) override {
receiver = rec;
}
void execute() override {
receiver([&] {std::cout << str1 << " " << str2 << std::endl;});
}
};
class Data2 : public Command {
private:
std::string str = "Jonney";
Receiver receiver;
public:
void setReceiver(Receiver rec) override {
receiver = rec;
}
void execute() override {
receiver([&] {std::cout << str << std::endl;});
}
};
class Invoker {
private:
std::stack<std::function<void()>> commands;
public:
void addCommand(std::function<void()> command) {
commands.push(command);
}
void execute() {
while (!commands.empty()) {
auto command = commands.top();
commands.pop();
command();
}
}
};
int main() {
auto namePrinter = [](std::function<void()> executor) {
executor();
};
auto data1 = Command{[&](){std::cout << "Suzuki Ichiro" << std::endl;}};
data1.setReceiver(namePrinter);
auto data2 = Command{[&](){std::cout << "Jonney" << std::endl;}};
data2.setReceiver(namePrinter);
Invoker invoker;
invoker.addCommand(std::bind(&Command::execute, data1));
invoker.addCommand(std::bind(&Command::execute, data2));
invoker.execute();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment