递归模板类别定义的基本案例要求

requirements on base cases for recursive template class definitions

本文关键字:案例 定义 递归      更新时间:2023-10-16

我在这里问的一个问题,我建议使用这样的一般模式来解决我的问题:

template <class... T>
class C;
template <>
class C<>
{
public:
    void f() {}
};
template <class T, class... Args>
class C<T, Args...> : public C<Args...>
{
public:
    using C<Args...>::f;
    void f(const T& t) { /*stuff*/ }
};

现在,我不完全理解为什么这种模式必须这样,所以我试图通过关于它如何工作的假设来调整它。在改编中,我想在带有1个基本情况下而不是0个模板参数的基本情况下结束递归,因此我更改了片段,如下所示:

template <class V, class... >
class C;
template <class V>
class C
{
public:
    void f() {}
};
template <class V, class T, class... Args>
class C<V, T, Args...> : public C<V, Args...>
{
public:
    using C<Args...>::f;
    void f(const T& t) { /*stuff*/ }
};

这里V应该继续通过,直到Args...为空,然后

template <class V>
class C
{
public:
    void f() {}
};

应该选择。但是,这引发了一个错误:

error: too few template parameters in template redeclaration
template <class V>
^~~~~~~~~~~~~~~~~~
note: previous template declaration is here
template <class V, class... >
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

所以我的假设是错误的。这实际上是如何工作的?我的适应需要正确的更改?

这里有两个错误:首先,不正确的专业化:

template <class V>
class C
{
    //...
};

应该是:

template <class V>
class C<V>
{
    //...
};

第二,不正确的using声明:

using C<Args...>::f;

应该是:

using C<V, Args...>::f;

您正确地忘记了咒语:

template <class V>
class C<V>
//    ^^^^  you missed this