繁体   English   中英

如何在部分类模板专业化中实现继承?

[英]How do I implement inheritance in a partial class template specialisation?

我想我只是想念一些小东西。 我想专门针对T =带有任何参数的模板类的实现而专门设计模板类的构造函数。 对不起,如果我的演唱会有点不对劲。 基本上,我需要允许锯齿状的2D数组,所以我可能有一个ArEl<ArEl<int>>并且我想ArEl<ArEl<int>>初始化所有的数组长度。

using namespace std;

template <typename T>
class ArEl {
 public:
  ArEl(size_t size = 0)
      : rSize(size), rArray(rSize ? new T[rSize]() : nullptr) {}
  ArEl(const ArEl& other);
  virtual ~ArEl() { delete[] rArray; }
  void swap(ArEl& first, ArEl& second);
  void redim(size_t size);

 private:
  std::size_t rSize;
  T* rArray;
};

template <typename T, typename T1>
class ArEl<ArEl<T>> : public ArEl<T1>{
  ArEl(size_t size = 0);
};

编辑:

我收到此错误:

error: template parameters not deducible in partial specialization:
 class ArEl<ArEl<T>> : public ArEl<T1>{

您使用错误的方式来专门化对象。

template<typename T, typename T1>表示需要提供两种数据类型,但是很明显,模板专业化唯一需要的是基础数组的数据类型。 如果期望ArEl<ArEl<T>>是专门的,则不应该花更多的钱:

template<typename T>
class ArEl<ArEl<T>> {
    /*Blah Blah Blah*/
};

不需要继承,也不需要第二种数据类型。

但是,我还要补充一点:首先,实际上不需要这种专业化。 如果您根本不编写专业化代码,则以下代码仍应照常运行:

ArEl<ArEl<int>> dim2Array(50);
//I'm assuming ArEl will have a member size() function
for(size_t index = 0; index < dim2Array.size(); index++) {
    //I'm assuming ArEl will have an operator[] overload
    dim2Array[index].redim(30);
}
//dim2Array is now 50 int arrays, each of size 30.

我假设您打算使用的功能具有以下类似功能,但确实需要模板专门化,如我上面所述:

ArEl<ArEl<int>> dim2Array(50, 30);
//dim2Array is now 50 int arrays, each of size 30.

但是,如果我是您,我将ArElArEl的实现,而是投入ArEl编写处理这种语法(而不是使用Matrix<T>类(对于N维,可能是Matrix<T, N> ))。您可以使用ArEl<T>作为构建基块进行构建,顺便说一句),尤其是因为我不认为您致力于为ArEl<ArEl<ArEl<int>>>或更深层次的人编写专业化ArEl<ArEl<ArEl<int>>> (是的,您正在尝试做到这一点,那么每个级别都需要有自己的专长)。

对整个类进行专业化意味着用专业化提供的成员替换所有成员。 你不要那样

一种选择是在基类中提供所有需要专门化的成员: BaseForA<T>将专门化,而A<T>将从中派生。

另一个方法是使用标签分配,这是一个示例,说明如何使用它根据type参数执行不同的操作。

#include <iostream>
#include <type_traits>

template<typename T>
struct tag {};

template<typename T>
struct A
{
private:
    template<typename U>
    A(std::size_t s, tag<A<U>>)
    {
        std::cout << "special constructor " << s << "\n";
    }

    A(std::size_t s, ...)
    {
        std::cout << "general constructor " << s << "\n";
    }
public:
    A(std::size_t s = 0) :
        A(s, tag<T>())
    {

    }
};

int main() 
{
    A<int> a;
    A<A<int>> b;
    A<A<long>> c;
    A<long> d;
}

住在科利鲁

如果我正确理解您的要求,则希望专用版本继承通用版本,然后在其之上添加一些内容。 这里的问题是您有一个专门的ArEl<ArEl<T>> ,您不能请求它的通用版本。

解决方案是使通用版本和专用版本为不同的类型。

template<typename T, bool D=true>
class ArEl { ...

template<typename T>
class ArEl<ArEl<T>>: 
    public ArEl<ArEl<T>, false> { ...

但是现在的问题是ArEl<T, true>ArEl<T, false>是不相关ArEl<T, false>兼容的!

解决方案是为它们引入一个通用的基类。

template<typename T>
class ArElBase {
     ... all functionality of ArEl
};

template<typename T, bool D=true>
class ArEl : public ArElBase<T> { 
   using ArElBase<T>::ArElBase;
   // nothing more
}; 

然后,专业化保持不变。

现在,您可以使用ArElBase通过指针或引用传递对象,但可以使用ArEl声明对象本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM