Skip to content

Instantly share code, notes, and snippets.

@isaac-ped
Created September 28, 2018 18:03
Show Gist options
  • Save isaac-ped/7bdb1cfa700fdf6d40f29a643842fa5e to your computer and use it in GitHub Desktop.
Save isaac-ped/7bdb1cfa700fdf6d40f29a643842fa5e to your computer and use it in GitHub Desktop.
Example of how I'm using CRTP
#include <vector>
#include <string>
#include <iostream>
class BaseCommand {
public:
virtual void execute() = 0;
};
class BaseExecutor {
private:
BaseExecutor() {};
public:
static BaseExecutor &get_instance() {
static BaseExecutor instance;
return instance;
}
};
template <typename ExecT, typename CmdT>
class Command : public BaseCommand {
public:
void execute() override {
BaseExecutor &exec = ExecT::get_instance();
static_cast<ExecT&>(exec).execute(static_cast<CmdT&>(*this));
}
};
////// SPECIALIZATION:
// The following compiles and works:
class ReadExecutor;
struct ReadABookCmd : public Command<ReadExecutor, ReadABookCmd> {
int isbn_no;
ReadABookCmd(int i) : isbn_no(i) {}
};
struct ReadAMothaFuckinBookCmd : public Command<ReadExecutor, ReadAMothaFuckinBookCmd> {
const std::string mothafuckin_book_name;
ReadAMothaFuckinBookCmd(std::string x) : mothafuckin_book_name(x) {}
};
class ReadExecutor :public BaseExecutor {
public:
void execute(ReadABookCmd &cmd) {
std::cout << "Reading a book " << cmd.isbn_no << std::endl;
}
void execute(ReadAMothaFuckinBookCmd &cmd) {
std::cout << "Reading a motha fuckin book " << cmd.mothafuckin_book_name << std::endl;
}
};
//// The following will not compile, because the ReadExecutor can't write a book
// class WriteABookCmd : Command<WriteExecutor, WriteABookCmd> {
// std::string book_name;
// }
class WriteExecutor;
struct WriteABookCmd : public Command<WriteExecutor, WriteABookCmd> {
const std::string contents;
WriteABookCmd(std::string c) : contents(c) {}
};
class WriteExecutor :public BaseExecutor {
public:
void execute(WriteABookCmd &cmd) {
std::cout << "Writing a motha fuckin book " << cmd.contents << std::endl;
}
};
void execute_commands(std::vector<BaseCommand*> &cmds) {
for (auto &cmd : cmds) {
cmd->execute();
}
}
int main() {
ReadABookCmd cmd1{1};
ReadABookCmd cmd2{2};
ReadAMothaFuckinBookCmd cmd3{"I AM A BOOK"};
WriteABookCmd cmd4{"Writing!"};
std::vector<BaseCommand*> cmds {
&cmd1, &cmd2, &cmd3, &cmd4
};
execute_commands(cmds);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment