具有专门构造函数的模板类

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

Ker*_* SB 2

我认为从基类派生类与这里的问题无关,这只是一个实现细节。您真正想要的是是否有一种方法可以部分专门化成员函数,例如构造函数。你想要这样的东西吗?

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 的答案。)

  • -1“提供成员(包括构造函数)专业化的唯一方法是专业化整个类。” 是不正确的。 (3认同)