首页 > 其他分享 >Command模式

Command模式

时间:2022-12-11 03:22:29浏览次数:37  
标签:std execute exec auto cmd 模式 command Command

一般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

相关文章