我正在尝试设计一个类型为T *的模板类,其声明如下:
template <class T>
class StructParamPublic<T*>
{
.....
protected:
T* m_pData;
};
可用于创建像这样的结构
StructParamPublic <FloatArrayStruct*> m_pFloatArray;
,其中
FloatArrayStruct
{
float* pData;
size_t arraySize;
};
但是,当我编译它时,我收到的错误是StructParamPublic不是模板类型。
如果我定义以下模板类
template <class T>
class StructParamPublic
{
.....
protected:
T m_Data;
};
然后这个错误消失了。 出于某些设计考虑,我不想将第二个定义添加到框架中。
我的解决方案是想出这样的东西
template <class T>
class StructParamPublic
{
.....
protected:
T* m_pData;
};
它编译得很好。
所以我的问题是:模板<class T> class StructParamPublic
是某种“基本模板类”和template <class T>class StructParamPublic<T*>
那种类的某种推导?
答案 0 :(得分:1)
你可以这样做:
template<typename T>
class StructParamPublic;
// ^ This just "forward declares" the class for all possible template values
template<typename U>
class StructParamPublic<U*> {
...
};
// ^ This is a partial specialization of the above class template. It will deduce the type of T from the pointer type that you instantiate the template with
如果您这样做,那么语法StructParamPublic<int*>
将是合法的,并且当您使用时,它会在模板中将类型T推断为int
。
一般情况下,当您拥有template<typename T> class < T::dependent_type > { ... };
时,您应该使用模板专门化来使其按照您期望的方式工作,并且这要求您首先制作非主流的“主要”模板,即使该主要模板实际上并没有做任何事情(除了作出声明)。
另请注意,您实际上并不需要在此处使用类型特征来强制执行指针类型要求。在上面的代码中,如果您尝试使用非指针类型,它只会找到主模板而不能找到真正的定义。如果您需要,可以在主模板"missing * in StructParamPublic<...>"
或类似内容中添加静态断言。
答案 1 :(得分:1)
您无需定义第二个类模板。你可以使用前瞻声明。
template <class T> class StructParamPublic;
然后你可以使用
template <class T>
class StructParamPublic<T*>
{
.....
protected:
T* m_pData;
};
答案 2 :(得分:1)
template <class T> class StructParamPublic<T*>;
是
的专业化template <class T> class StructParamPublic;
因此,对于您的问题,您有几种可能性:
(部分)专业化
template <class T> class StructParamPublic;
template <class T>
class StructParamPublic<T*>
{
// code
protected:
T* m_pData;
};
StructParamPublic<int>
会导致未定义类的错误。
或static_assert
template <class T>
class StructParamPublic
{
static_assert(std::is_pointer<T>::type, "type should be a pointer type");
using value_type = typename std::remove_pointer<T>::type;
// code
protected:
T m_pData; // or value_type* m_pData;
};
由于StructParamPublic<int>
, static_assert
会导致干净错误。
或更改参数的含义作为解决方案。
template <class T>
class StructParamPublic
{
.....
protected:
T* m_pData;
};
此处使用 StructParamPublic<int>
,而之前的解决方案需要StructParamPublic<int*>
。