一般command大概interface:
struct ICommand{ virtual void execute() = 0; virtual void undo() = 0; }
今年cppCon讲了一种非常简单的static 模式实现:
Using Modern C++ to Eliminate Virtual Functions - Jonathan Gopel - CppCon 2022
我尝试用了下这个方法做了下static command:
command.ixx
export module command; export template<typename EXEC_FF, typename UNDO_FF> struct command{ EXEC_FF exec; UNDO_FF ff; void execute(){exec();} void undo(){ff();}; }; template<typename T1, typename T2> command(T1, T2)-> command<T1, T2>;
main.cpp
#include <iostream> #include <tuple> #include <vector> import command; template<typename T> concept is_command = requires (T cmd){ {cmd.execute()}-> std::same_as<void>; {cmd.undo()}-> std::same_as<void>; }; template<typename T, typename ... Ts> concept same_as_any = (... or std::same_as<T,Ts>); template<is_command ... command_t> struct commandPool{ template<same_as_any<command_t...> T> auto store(T cmd){ std::get<std::vector<T>>(cmds).emplace_back(cmd); } void execute(){ auto _exec = [](auto & vec_cmd){ for(auto & cmd : vec_cmd){ cmd.execute(); } }; std::apply([this,_exec](auto & ... cmds_list){ (_exec(cmds_list),... ); }, cmds); } void undo(){ auto _exec = [](auto & vec_cmd){ for(auto & cmd : vec_cmd){ cmd.undo(); } }; std::apply([this,_exec](auto & ... cmds_list){ (_exec(cmds_list),... ); }, cmds); } private: std::tuple<std::vector<command_t>...> cmds; }; struct Command2Type{ void execute(){ std::cout << "command 2 type execute\n"; } void undo(){ std::cout << "command 2 type undo\n"; } }; int main() { command cmd{ [](){std::cout << "lambda command execute\n";}, [](){std::cout <<"lambada command undo\n";} }; commandPool<decltype(cmd), Command2Type> cmdPools; cmdPools.store(std::move(cmd)); cmdPools.store(Command2Type()); cmdPools.execute(); cmdPools.undo(); return 0; }
输出:
lambda command execute command 2 type execute lambada command undo command 2 type undo
实际应用中,commandPools设计成软件的单例。把command_type 定义出来,在编译时间确定。
标签:std,execute,exec,auto,cmd,模式,command,Command From: https://www.cnblogs.com/gearslogy/p/16972777.html