Variadic template function: specialize head/tail and empty base case

c++, c++11, template-meta-programming, templates, variadic-templates

Solution

I would say it is normally a better idea to overload function templates rather than specializing them:

struct MyClass {
    template<typename... Tail>
    static int count() {
        return 0;
    }

    template<char Head, char... Tail>
    static int count() {
        return 1 + count<Tail...>();
    }
};

#include <iostream>

int main() {
    std::cout << MyClass::count<'f','o','o'>();
}

And here is a live example. I would also mention that the built-in operator `sizeof...` could be used for this purpose:

struct MyClass {
    template<char... Chars>
    static int count() {
        return sizeof...(Chars);
    //         ^^^^^^^^^
    }
};

Problem

I'd like to have a variadic template function inside a class. The variadic template arguments are chars which should be processed in a loop-like manner. So I thought of writing it like in haskell with head/tail splitting the list until a base case (empty list) is reached. As an example, let's just count the number of arguments given (only a minimal example). I came up with the following code: ``` struct MyClass { template<char ...X> static int count(); }; template<> int MyClass::count<>() { return 0; } template<char Head, char ...Tail> int MyClass::count<Head, Tail...>() { return 1 + count<Tail...>(); } ``` However, this doesn't seem to work: ``` prog.cpp:12:35: error: function template partial specialization ‘count<Head, Tail ...>’ is not allowed prog.cpp:12:5: error: prototype for ‘int MyClass::count()’ does not match any in class ‘MyClass’ prog.cpp:3:16: error: candidate is: template<char ...X> static int MyClass::count() ``` How can I achieve this? I know that partial specialization isn't supported for functions. But I thought that specializing a variadic template into head/tail and empty base case version isn't a partial specialization but a full specialization, but maybe I'm wrong? Do I need to write this as a class instead of a function? I found examples (printf) which implement a base case without using the template syntax at all. But I guess that my case is different, since the call for printf doesn't use template syntax but type deduction, so `printf(tail...)` calls `printf()` if `tail` is empty. On the other side, in my case, when calling the base case, `count<>()` isn't the same as `count()`.

Original source