继承时删除重复的模板typename条目

时间:2015-05-14 10:51:51

标签: c++ templates boost c++14 template-meta-programming

我有一个继承自的模板类(从现在起作为父级引用)。

模板类初始化一个融合列表成员变量,该变量包含子类中指定的类和构造函数。

template<typename... ITEM_TYPES>
using List = boost::fusion::list<ITEM_TYPES...>;

template<typename... CHILDREN_TYPES>
class ElementContainer 
{ 
protected:
    const List<CHILDREN_TYPES...> children;
public:
     ElementContainer(CHILDREN_TYPES&&... args) : children(forward<CHILDREN_TYPES>(args)...) {}
};

子类的示例:

class XMLSignatureDocument : public ElementContainer<XMLDeclarationElement, SignatureXMLElement>
{
public:
    XMLSignatureDocument() :ElementContainer(
        XMLDeclarationElement("<?xml version=\"1.0\" encoding=\"utf-8\"?>"),
        SignatureXMLElement("<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></signature>"
        )) {};
};

当我创建这样的子类时,我必须在列表中指定类的类型两次:

进入“继承自”规范:

class XMLSignatureDocument : public ElementContainer<XMLDeclarationElement, SignatureXMLElement>

以及当我指定各个类的构造函数参数时:

XMLSignatureDocument() :ElementContainer(
    XMLDeclarationElement("<?xml version=\"1.0\" encoding=\"utf-8\"?>"),
    SignatureXMLElement("<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></signature>"
    )) {};

我只想指定一次 - 当我还指定构造函数参数时,如下所示:

class XMLSignatureDocument : public ElementContainer<...>
{
public:
    XMLSignatureDocument() :ElementContainer(
        XMLDeclarationElement("<?xml version=\"1.0\" encoding=\"utf-8\"?>"),
        SignatureXMLElement("<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></signature>"
        )) {};
};

并且仍然在父类中创建列表的编译时间。

如果不可能,我没有被100%锁定在这个设计中 - 如果可以使用其他设计并完成同样的我想听到它。

我正在使用Visual Studio 2014(v140)(c ++ 14)工具集进行编译和升级库。

2 个答案:

答案 0 :(得分:5)

您可以这样做:在类声明中指定类型,并对构造函数参数使用通用初始化语法(尽管它不适用于显式构造函数):

class XMLSignatureDocument : public ElementContainer<XMLDeclarationElement, SignatureXMLElement>
{
public:
    XMLSignatureDocument() :ElementContainer(
        {"<?xml version=\"1.0\" encoding=\"utf-8\"?>"},
        {"<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></signature>"}
        ) {};
};

答案 1 :(得分:0)

您可以在ElementContainer构造函数中构建模板参数类型。这将适用于explicit构造函数,但仅限于它们只需要一个参数。

ElementContainer构造函数更改为模板函数,该函数将参数转发到CHILDREN_TYPES构造函数:

template <typename... Args>
ElementContainer(Args&&... args) 
    : children(CHILDREN_TYPES{std::forward<Args>(args)}...) {}

然后你可以自己传递字符串:

XMLSignatureDocument() :ElementContainer(
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
        "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"></signature>") {};