【问题标题】:C++ specialized template inherit from non-specialized versionC++ 专用模板继承自非专用版本
【发布时间】:2010-01-13 20:11:57
【问题描述】:

我试图解决一个问题,但找到了不同的解决方案。 但是出于好奇想知道以下是否可能:

template< class > struct S;
template< > struct S< Foo > : struct< Foo > {};

我希望能够从专用结构继承非专用结构。上面的示例不起作用,因为继承的结构是专用结构,导致无限递归。

一种可能的解决方案是添加第二个模板参数,比如 bool special ,这样默认值为 false,而专用模板的参数为 true。但是,由于实例化需要指定额外的参数,这让事情变得有点混乱。

还有其他方法可以实现上述吗?

最初的问题是实现矩阵矩阵,其中矩阵本身可能有额外的运算符,这取决于组成矩阵是否具有这些运算符。我希望这是有道理的。同时,不同的专用矩阵需要属于相同的基类,同时保持相同的名称,尽管模板参数不同。我认为可能有一种方法可以使用 enable_if 和 type traits

【问题讨论】:

  • 第一个反问是你想用这个解决什么样的问题?

标签: c++ inheritance templates


【解决方案1】:

您可以将所有通用的东西保存在一个单独的类型中,并使用您的专业进行扩展:

template <typename> struct S_generic { /* generic stuff here */ };

template <typename T> struct S : public S_generic<T> { /* nothing here */ };
template <> struct S<Foo> : public S_generic<Foo> { /* extra stuff here */ };

编辑:或者,如果您不喜欢额外的名称,在实例化模板时使用额外标志而不混乱的方法是使用默认值:

template <typename T, bool fully_defined=true> struct S;
template <typename T> struct S<T,false> { /* generic stuff here */ };

template <typename T> struct S<T,true> : public S<T,false> {};
template <> struct S<Foo,true> : public S<Foo,false> { /* extra stuff here */ };

【讨论】:

  • 这就是我最终要做的。我试图避免的是有两个不同的名字。我认为可能有一种方法可以使用 enable_if 和 type traits。
  • 没有理由添加所有额外的 enable_if 或类型特征的复杂性,只需使用非专业化和专业化可以继承的公共基础。 BlahBaseblah_base 很常见。
  • 在这一点上,与其说是实际问题,不如说是好奇,“我想知道它是否可以做到这一点?”。
  • 这是很棒的技术。在某些情况下,使用额外的名称,您可能还需要在派生类中定义额外的 ctors(非继承)或赋值运算符。模板引擎可以为你生成这个。
【解决方案2】:

一种可能的解决方案是添加第二个模板参数,比如 bool special ,这样默认值为 false,而专用模板的参数为 true。但是,由于实例化需要指定额外的参数,这让事情变得有点混乱。

template&lt;class Foo, bool flag = false&gt;可以,所以第二个参数是可选的。

【讨论】:

    【解决方案3】:

    我喜欢 Mike Seymour 的回答,但您不必在任何地方都指定真假。

    你可以有这样的东西:

    template<class T, bool = false>
    class Object {
        void abstract_method();
    };
    
    // Now for your derived specialized type do this
    
    template<>
    class Object<SpecialObject> : Object<SpecialObject, true> { 
        // override any methods
    };
    

    我们只需要将Object模板类bool默认为false,然后当我们实例化Object&lt;SpecialObject&gt;()时,它现在已经为其分配了完整的类型Object&lt;SpecialObject, false&gt;,所以现在我们只需要要做的是告诉编译器找到与Object&lt;SpecialObject, true&gt; 匹配的潜在不同特化,我们在上面的: 之后执行此操作。

    现在编译器将选择其中包含abstract_method 的类,即使它默认为false,我们已经选择了带有false 的特化,因为当编译器第一次遇到@987654331 类型时,该默认参数@ 它实际上与Object&lt;SpecialObject, false&gt; 相同,所以现在当我们通过true 时,我们明确表示我不在乎谁使用了默认的false 参数现在尝试使用true 找到不同的专业化,并且有效。

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多