【问题标题】:Can you template specialize a subclass that is not templated?您可以模板专门化一个未模板化的子类吗?
【发布时间】:2013-01-08 16:08:02
【问题描述】:

这是我的情况:

基类,无模板类型:

struct Thing
{

} ;

模板类,扩展了那个基类

template <typename T> struct VertexWriter : public Thing
{ 
    template <typename S>
    bool intersects( S* otherThing )
    {
        // has a body, returns T or F
    }
} ;

派生类,CONCRETE 类型(无模板)

struct Rocket : VertexWriter<VertexPNCT>
{
    template <typename S>
    bool intersects( S* otherThing ) ; // WANTS TO OVERRIDE
    // implementation in VertexWriter<T>
} ;

但是template typename&lt;S&gt; bool VertexWriter&lt;T&gt;::intersects不能标记为虚拟,因为它是一个模板类。

有许多类派生自 VertexWriter&lt;VertexPNCT&gt; 特化,因此模板特化 VertexWriter&lt;VertexPNCT&gt; 将不起作用。

所以正常的做法是提供模板特化。

但是Rocket 指定它是一个VertexWriter&lt;VertexPNCT&gt;,所以它不再是一个模板类。它可以专门化或覆盖intersects,就好像它是一个虚函数一样?

【问题讨论】:

    标签: c++ templates template-specialization virtual-functions


    【解决方案1】:

    您可以在S 上模板VertexWriter 并使intersects 成为该类模板的虚函数

    template <typename T, typename S> struct VertexWriter : public Thing
    { 
        virtual bool intersects( S* otherThing )
        {
            // has a body, returns T or F
        }
    } ;
    

    现在您可以在派生类中覆盖intersects

    template<typename S>
    struct Rocket : VertexWriter<VertexPNCT, S>
    {
        virtual bool intersects( S* otherThing ) ; // WANTS TO OVERRIDE
        // implementation in VertexWriter<T>
    }
    

    【讨论】:

      【解决方案2】:

      不,正如你所说,你不能使用虚函数,它会提供运行时多态性。

      也就是说,根据您在更改课程布局方面的余地,您也许可以使用 CRTP 做一些事情。

      template <typename T, typename Derived> struct VertexWriter : public Thing
      { 
          template <typename S>
          bool intersects( S* otherThing )
          {
              return static_cast<Derived*>(this)->insersects_impl(otherThing);
          }
      
          template<typename S>
          bool insersects_impl( S* otherThing)
          {
               // Whatever
          }
      } ;
      
      struct Rocket : VertexWriter<VertexPNCT, Rocket>
      {
         template <typename S>
         bool intersects_impl( S* otherThing ) { ... } // WANTS TO OVERRIDE
                             // implementation in VertexWriter<T>
      } ;
      

      intersects 的基本实现只是转发给 CRTP 函数。如果派生类覆盖它,它将使用覆盖,否则它将回退到默认值。请注意,这确实会使您的类层次结构复杂化,但可能会完成您正在寻找的内容。

      【讨论】:

        【解决方案3】:

        不,你不能。

        模板化的成员函数不能是虚函数。

        VertexWriter 是模板化、专用化还是普通类都没有关系。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-01
          相关资源
          最近更新 更多