我想我只是错过了一些小东西。我想为一个实现专门化模板类的构造函数,其中T=带有任何参数的模板类。对不起,我的嗓音有点不好。基本上,我需要允许锯齿状的2D阵列,所以我可能有一个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.
但如果我是你,我会放弃ArEl
的实现,而是投资于编写一个Matrix<T>
类(或者可能是Matrix<T, N>
,用于N维)来处理这种语法(顺便说一句,你可以使用ArEl<T>
作为构建块来构建它),尤其是因为我不认为你会致力于为ArEl<ArEl<ArEl<int>>>
或更深层次编写专业知识(是的,按照你的尝试方式,每个级别都需要自己的专业知识)。
专门化整个类意味着用专门化提供的成员替换所有成员。你不想那样。
一种选择是在基类中提供所有需要专门化的成员:BaseForA<T>
将是专门化的,A<T>
将从中派生
另一种方法是使用标记调度,下面是一个如何使用它根据类型参数执行不同操作的示例。
#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;
}
在Coliru 上直播
如果我理解正确,你希望专业版本继承通用版本,然后在上面添加一些东西。这里的问题是你有一个专门的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>
是不相关的,不兼容的!
解决方案是为它们引入一个公共基类。
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声明对象本身。