lo tolmencre
lo tolmencre

Reputation: 3934

requirements on base cases for recursive template class definitions

To a question I asked here, I got the suggestion to use a general pattern like this to solve my problem:

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*/ }
};

Now, I don't fully understand why this pattern has to be like this, so I tried to adapt it by a hypothesis I had about how this works. In the adaption I wanted to end the recursion in a base case with 1 and not 0 template arguments, so I changed the snippet as follows:

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*/ }
};

Here V is supposed to keep getting passed on until Args... is empty, then

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

is supposed to be chosen. However this throws an error:

error: too few template parameters in template redeclaration
template <class V>
^~~~~~~~~~~~~~~~~~

note: previous template declaration is here
template <class V, class... >
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

So my hypothesis was wrong. How does this actually work and what would be the correct changes for my adaption need to be?

Upvotes: 1

Views: 142

Answers (2)

xinaiz
xinaiz

Reputation: 7788

Two errors here: First, incorrect specialization:

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

Should be:

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

Second, incorrect using declaration:

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

Should be:

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

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 477010

You forgot the spell the specialization correctly:

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

Upvotes: 1

Related Questions