lundi 29 juin 2015

End of recursion specialization of inner template class

Consider this working code:

#include <typeinfo>

template <typename ...> struct A;

template <typename First, typename... Rest>
struct A<First, Rest...> {
    static void execute() {
        std::cout << typeid(First).name() << ' ';
        A<Rest...>::execute();
    }
};

template <>
struct A<> {
    static void execute() {}  // End of recursion.
};

int main() {
    A<char, bool, int>::execute();  // char bool int
}

So why does the end of recursion below not compile (error statements provided in comments):

#include <typeinfo>

template <typename ...> struct A;

template <typename... Ts>
struct A {
    template <typename...> struct B;
    template <typename...> static void execute();
};

template <typename... Ts>
template <typename First, typename... Rest>
struct A<Ts...>::B<First, Rest...> {
    static void execute() {
        std::cout << typeid(First).name() << ' ';
        B<Rest...>::execute();
    }
};

template <typename... Ts>
template <> // invalid explicit specialization before '>' token
struct A<Ts...>::B<> {  // template parameters not used in partial specialization: Ts
    static void execute() {}  // End of recursion
};

template <typename... Ts>
template <typename... Us>
void A<Ts...>::execute() {
    B<Us...>::execute();
}

int main() {
    A<char, bool, int>::execute<double, short, float>();
}

It does work when I use this end of recursion instead of above:

template <typename... Ts>
template <typename Last>
struct A<Ts...>::B<Last> {
    static void execute() {std::cout << typeid(Last).name();}
};

But I just want to know what's wrong with the original attempt.

Aucun commentaire:

Enregistrer un commentaire