【问题标题】:Can parameter type and count be specified by a template参数类型和计数可以通过模板指定吗
【发布时间】:2015-03-14 20:22:08
【问题描述】:

我希望在常规(非模板)类中拥有一个函数模板,它分配具有所需参数的派生类并返回一个指向基类的指针:

class Factory {
public:
    BaseClass_T * createObject(parameters) { return new Derived_T(parameters); }
};

到目前为止,我只使用参数类型不同但数量相同的模板。由于我的不同派生类具有不同的构造函数签名,我想知道是否有一种方法可以对其进行模板化并通过模板指定生成函数的参数类型和计数,如下所示:

Factory f;
f.createObject<Derived1, void>(); // create createObject() for Derivev1() constructor
f.createObject<Derived2, int, double>(); // create createObject() for Derived2(int, double) constructor

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    您可以使用可变参数模板:

    #include <utility>
    
    struct BaseClass_T { ~virtual BaseClass_T() = default; };
    
    struct Factory
    {
        template <typename Der, typename ...Args>
        BaseClass_T * create(Args &&... args)
        { 
            return new Der(std::forward<Args>(args)...);
        }
    };
    

    更好的设计是让您的工厂返回std::unique_ptr&lt;BaseClass_T&gt;

    #include <memory>
    
    struct SaneFactory
    {
        template <typename Der, typename ...Args>
        std::unique_ptr<BaseClass_T> create(Args &&... args)
        { 
            return std::make_unique<Der>(std::forward<Args>(args)...);
        }
    };
    

    【讨论】:

    • 为什么析构函数必须是= default?仅仅声明它是虚拟的还不够吗?毕竟只能有一个析构函数,不是吗?
    • 另外,我立即使用该指针将其添加到管理对象的对象树中,所以我认为我不需要unique_ptr
    • @dgtech:需要显式或隐式定义析构函数。只是声明它会抑制它的隐式定义。
    • @dgtech:你总是需要unique_ptr,除非你讨厌自己或你的用户。没有额外的成本,它使代码自我记录。写下你的意思,而不是偶然发生的事情。在这种情况下,您的意思是工厂函数返回一个责任包。
    • @dgtech:您可以在 API 边界处使用release(),以便明确的职责转移成为小型、紧密、可测试的包装接口的一部分。但是要保持代码的核心干净。换句话说,尽量减少理解代码功能所需的脑力劳动。
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多