Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can a c++;模板模式取代了不断增长的联盟?_C++_Templates - Fatal编程技术网

C++ Can a c++;模板模式取代了不断增长的联盟?

C++ Can a c++;模板模式取代了不断增长的联盟?,c++,templates,C++,Templates,我有一个简单的类,它允许一个中断(或其他例程)来安排一个函数在主循环代码的下一个过程中运行。这是通过使用联合来描述不同的可能参数模式来实现的 按原样,添加新类型的参数模式需要 为图案添加typedef 向联合中添加一个struct,以表示参数 添加一个adddoore声明和函数来处理add 更新循环代码切换语句以处理新的模式类型 每一个新的参数模式都需要做一点工作。我正在学习模板,想知道这个类是否可以重写为使用模板来简化添加额外的参数模式?如果是这样的话,模式是否也可以扩展以允许不同数量的参数

我有一个简单的类,它允许一个中断(或其他例程)来安排一个函数在主循环代码的下一个过程中运行。这是通过使用
联合来描述不同的可能参数模式来实现的

按原样,添加新类型的参数模式需要

  • 为图案添加
    typedef
  • 向联合中添加一个
    struct
    ,以表示参数
  • 添加一个
    adddoore
    声明和函数来处理add
  • 更新
    循环
    代码切换语句以处理新的模式类型
  • 每一个新的参数模式都需要做一点工作。我正在学习模板,想知道这个类是否可以重写为使用模板来简化添加额外的参数模式?如果是这样的话,模式是否也可以扩展以允许不同数量的参数

    typedef void (*looper_runner1)(uint32_t arg1, uint16_t arg2);
    typedef void (*looper_runner2)(uint8_t *arg1, uint16_t arg2);
    
    struct LoopDooer
    {
        uint16_t type;
        union {
            struct
            {
                uint32_t arg1;
                uint16_t arg2;
                looper_runner1 fn;
            } type1;
            struct
            {
                uint8_t *arg1;
                uint16_t arg2;
                looper_runner2 fn;
            } type2;
        } dooer;
    };
    
    class Looper
    {
    
    public:
    
        Looper();
        bool addDooer(looper_runner1 fn, uint32_t arg1, uint16_t arg2);
        bool addDooer(looper_runner2 fn, uint8_t *arg1, uint16_t arg2);
        void loop();
    
    private:
        /* ... actual methods not relevant to question */
    };
    
    bool Looper::addDooer(looper_runner1 fn, uint32_t arg1, uint16_t arg2)
    {
        LoopDooer *p = new LoopDooer();
        p->type = 1;
        p->dooer.type1.fn = fn;
        p->dooer.type1.arg1 = arg1;
        p->dooer.type1.arg2 = arg2;
        return _add(p);
    }
    
    bool Looper::addDooer(looper_runner2 fn, uint8_t *arg1, uint16_t arg2)
    {
        LoopDooer *p = new LoopDooer();
        p->type = 2;
        p->dooer.type2.fn = fn;
        p->dooer.type2.arg1 = arg1;
        p->dooer.type2.arg2 = arg2;
        return _add(p);
    }
    
    // To be called from main loop
    void Looper::loop()
    {
        LoopDooer *p;
    
        /* some code removed that just gets next LoopDooer into pointer p */
    
        // Do it
        switch (p->type)
        {
        case 1:
            p->dooer.type1.fn(p->dooer.type1.arg1, p->dooer.type1.arg2);
            break;
        case 2:
            p->dooer.type2.fn(p->dooer.type2.arg1, p->dooer.type2.arg2);
            break;
        }
        // Delete it
        delete p;
    }
    

    您在这里尝试的所有操作都可以通过
    std::function
    和lambdas直接完成。对于任意参数类型,它们实现您想要的所有逻辑

    #include<functional>
    
    using LoopDooer = std::function<void()>;
    
    template<typename F, typename... Args>
    bool Looper::addDooer(F f, Args&&... args) {
        return _add([=]{ f(args...); });
    }
    
    void Looper::loop() {
        LoopDooer dooer = /* extract LoopDoer from container */;
        dooer();
    }
    
    #包括
    使用loopdoore=std::函数;
    模板
    bool Looper::adddoorer(F,Args&&…Args){
    返回_add([=]{f(args…;});
    }
    void Looper::loop(){
    loopdooter=/*从容器中提取LoopDoer*/;
    doore();
    }
    

    还要注意,使用
    new
    /
    delete
    手动管理内存是个坏主意。至少要使用
    std::unqiue_ptr
    ,但实际上根本不需要任何动态分配。您使用的任何容器都可能直接包含
    loopdoore
    s。

    您在这里尝试的所有操作都可以通过
    std::function
    和lambdas直接完成。对于任意参数类型,它们实现您想要的所有逻辑

    #include<functional>
    
    using LoopDooer = std::function<void()>;
    
    template<typename F, typename... Args>
    bool Looper::addDooer(F f, Args&&... args) {
        return _add([=]{ f(args...); });
    }
    
    void Looper::loop() {
        LoopDooer dooer = /* extract LoopDoer from container */;
        dooer();
    }
    
    #包括
    使用loopdoore=std::函数;
    模板
    bool Looper::adddoorer(F,Args&&…Args){
    返回_add([=]{f(args…;});
    }
    void Looper::loop(){
    loopdooter=/*从容器中提取LoopDoer*/;
    doore();
    }
    

    还要注意,使用
    new
    /
    delete
    手动管理内存是个坏主意。至少要使用
    std::unqiue_ptr
    ,但实际上根本不需要任何动态分配。无论您使用什么容器,都应该直接包含
    loopdoore
    s。

    我不知道模板是正确的方法。它们用于操作相同但数据类型不同的情况。您应该考虑查看STD::BIN,在不添加操作的情况下添加新类型是基于继承的多态性的经典用例。我会从那里开始寻找灵感。有一些方法可以让它比添加一个全新的派生类更简洁,但它们的想法还是一样的,我不知道模板是正确的方法。它们用于操作相同但数据类型不同的情况。您应该考虑查看STD::BIN,在不添加操作的情况下添加新类型是基于继承的多态性的经典用例。我会从那里开始寻找灵感。有一些方法可以使它比添加一个全新的派生类更简洁,但它们仍然有相同的想法。太好了,谢谢!我怀疑会有更容易的事情发生。我学习和写了很多C++之前lambdas和当它几乎没有模板。从那以后(25年多了?)我一直在用其他更高级的语言写作。现在我必须回到C++来为ARDUINO编写一些代码,但是我用以前的方式写在我的脑子里。很高兴有一个开始学习的指针@D'AtAgAnEngEngEngBrbasa是的,较新的C++特性使编写更高级抽象变得更容易。还要注意,
    std::function
    并没有真正实现您的方法。它使用类型擦除。然而,自C++17以来,您所使用的联合方法也在标准库中实现为
    std::variant
    ,因此实际上没有任何理由再手动编写此类联合。Lambda在很大程度上只是句法上的糖。您可以编写一个模板函子。(但这需要一个完整的类定义,而lambda可以写在表达式中。)太好了,谢谢!我怀疑会有更容易的事情发生。我学习和写了很多C++之前lambdas和当它几乎没有模板。从那以后(25年多了?)我一直在用其他更高级的语言写作。现在我必须回到C++来为ARDUINO编写一些代码,但是我用以前的方式写在我的脑子里。很高兴有一个开始学习的指针@D'AtAgAnEngEngEngBrbasa是的,较新的C++特性使编写更高级抽象变得更容易。还要注意,
    std::function
    并没有真正实现您的方法。它使用类型擦除。然而,自C++17以来,您所使用的联合方法也在标准库中实现为
    std::variant
    ,因此实际上没有任何理由再手动编写此类联合。Lambda在很大程度上只是句法上的糖。您可以编写一个模板函子。(但这需要一个完整的类定义,而lambda可以写在表达式中。)