【问题标题】:Why can I omit the template parameter specification in some cases?为什么在某些情况下可以省略模板参数规范?
【发布时间】:2021-04-29 12:20:08
【问题描述】:

我有一个问题,因为我无法解释为什么有些东西在我可能犯了错误的地方有效。也许有人可以通过向我解释为什么会这样来帮助我改善我的 C++ 文化。

为了提高透明度,我将代码简化了很多。

我有一个这样的模板虚拟类:

    template<class Node>
    class tXmlNode
    {
    public:
        tXmlNode();
        virtual ~tXmlNode();

    protected:
        Node* node;
    }
    ;

由此我派生出几个类。

我主要从它派生出另一个模板类,例如这个:

    template<class Part>
    class tXmlMove : public tXmlNode<Part>
    {
    public:
        tXmlMove(Part* part);
        ~tXmlMove();

    protected:
        int n_translate;
    };

有了这个实现(简化为构造函数):

    template<class Part>
    inline tXmlMove<Part>::tXmlMove(Part* part) : tXmlNode<Part>(part)
    {
        //do some construction
    }
    ;

如您所见,我将部分构造委托给父类构造函数。工作正常。

现在我有另一个派生类,但它是从一个专门的父类派生的(专门化是一种自专门化,但来自具有类似专门父类的其他类,它与这个完全一样):

    class tXmlCaseDefinition : public tXmlNode<tXmlCaseDefinition>
    {
    public:
        tXmlCaseDefinition();
        tXmlCaseDefinition(const pugi::xml_node& parent);

        ~tXmlCaseDefinition();

    protected:
        int n_shapes;
    }
    ;

(我猜是因为专业化,我不需要把这个类构造成模板类。)

它的非默认构造函数实现如下:

nXml::tXmlPart::tXmlPart(
    const pugi::xml_node& parent, 
    const int npos) : tXmlNode(parent, npos), this_id(""), this_type(""), description("")
{
}
;

如您所见,我没有使用tXmlNode&lt;tXmlCaseDefinition&gt;(parent,npos) 委托给父构造函数,而只是使用tXmlNode(parent,npos)。我没有注意这一点,它出于某种神秘的原因而起作用。我简直无法理解为什么。谁能解释一下?

我还需要使用tXmlNode&lt;Part&gt;(part) 还是我可以使用tXmlNode(part) 来代替不是从专用父类派生的类,还是只有当我有一个专门化的父类时才有可能?

非常感谢!

【问题讨论】:

    标签: c++ templates constructor


    【解决方案1】:

    在模板类的定义中(更正式地说,“当前实例化”),有一个叫做injected-class-name的东西,它只是模板的名称,没有参数。例如:

    template<class T>
    struct Foo
    {
       Foo* ptr; // refers to Foo<T>
    }; 
    

    当您从模板类派生时,会继承基类的 injected-class-name。因此,您还可以参考基类没有模板参数(假设名称是可访问的;某些祖先没有从它私下继承):

    template<class T>
    struct Base
    {
    };
    
    struct Derived : Base<int>
    {
       Base* ptr; // refers to Base<int>
    };
    

    cppreference 很好地总结了这里的所有标准语言(参考 [temp.local]、[basic.lookup] 和 [basic.scope.class])

    【讨论】:

    • 所以基本上我可以为任何构造函数委托省略这个,不是吗?
    • 是的,您可以省略模板参数(包括&lt;&gt;)。例如,如果您使用来自同一基的多重继承(只是在不同类型上模板化),事情就会变得棘手。
    猜你喜欢
    • 2014-07-11
    • 2015-01-14
    • 2018-05-04
    • 1970-01-01
    • 2016-06-10
    • 2020-11-29
    • 2022-11-25
    • 1970-01-01
    • 2018-09-08
    相关资源
    最近更新 更多