Created
September 28, 2018 18:03
-
-
Save isaac-ped/7bdb1cfa700fdf6d40f29a643842fa5e to your computer and use it in GitHub Desktop.
Example of how I'm using CRTP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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