Mun*_*nro 5 c++ templates constructor metaprogramming
考虑以下设计的模板化数组定义示例:
template <typename t, unsigned int n> class TBase
{
protected:
t m_Data[n];
//...
};
template <typename t, unsigned int n> class TDerived : public TBase<t, n>
{
TDerived()
{
}
};
Run Code Online (Sandbox Code Playgroud)
我可以专门化这种类型为长度为2的数组提供非默认构造函数,如下所示:
template <typename t> class TDerived<t, 2> : public TBase<t, 2>
{
public:
TDerived(const t& x0, const t& x1)
{
m_Data[0] = x0;
m_Data[1] = x1;
}
};
int main()
{
TDerived<float, 2> Array2D_A(2.0f, 3.0f); //uses specialised constructor
TDerived<float, 3> Array3D_A; //uses default constructor
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法我可以创建一个类,在编译时有不同的构造函数选项约束模板参数,而不需要为每个变体进行完整的类专门化?
换句话说,是否有某种方式我可以在TBase类中拥有专门的构造函数,而不需要TDerived在保留功能的同时创建中间步骤TBase?
我认为从基类派生类与这里的问题无关,这只是一个实现细节。您真正想要的是是否有一种方法可以部分专门化成员函数,例如构造函数。你想要这样的东西吗?
template <typename T, int N> class Foo
{
Foo(); // general
template <typename U> Foo<U, 2>(); // specialized, NOT REAL CODE
};
Run Code Online (Sandbox Code Playgroud)
这是行不通的。你总是必须让整个班级变得专业化。原因很简单:在知道存在哪些成员函数之前,您必须首先知道类的完整类型。考虑以下简单的情况:
template <typename T> class Bar
{
void somefunction(const T&);
};
template <> class Bar<int>
{
double baz(char, int);
};
Run Code Online (Sandbox Code Playgroud)
现在Bar<T>::somefunction()取决于T,但该函数仅在不存在时才存在,因为是一个完全不同的类。TintBar<int>
或者考虑另一种专业化template <> class Bar<double> : public Zip {};——甚至类的多态性质在专业化中也可能完全不同!
因此,提供成员(包括构造函数)特化新声明的唯一方法是特化整个类。(您可以专门化现有函数的定义,请参阅@Alf 的答案。)