Template class specialization with a template template argument

76 views Asked by At
#include <tuple>
#include <iomanip>

template <typename T, typename ...L>
struct foo{};

template <typename T>
struct bar{
    using toto = T;
};

template <template<typename T, typename ...L> class F>
struct bar<F>{
    using toto = T
};

int main(){
    bar<foo<int,char,char>> a;
}

I want to specialize bar when the argument is a class that has at least one template argument <typename T, typename ...L>

I tried :

template <template<typename T, typename ...L> class F>
struct bar<F<T,L...>>{
    using toto = T
};

and

template <template<typename , typename ...> class F, typename T, typename ...L>
struct bar<F<T,L...>>{
    using toto = T
};

which may have made sense, but I couldn't get it right

3

There are 3 answers

2
Marco A. On BEST ANSWER

You forgot a lot of stuff on your sample, syntactically speaking

template <typename T, typename... L>
struct foo{};

template <typename T>
struct bar {
    using toto = T; // Semicolon missing
};

template <template<typename, typename...> class F, typename T, typename... L>
struct bar<F<T,L...>> { // Wrong pack expansion
    using toto = T;
};

int main() { // () missing

    bar< foo<int,char,char> > a; // Pass the parameters to foo since you're
                                 // partially specializing bar to just do that
}

Example on ideone

3
TartanLlama On

Your ideone code just has a bunch of typographical errors:

struct bar<F<T,...L>>{
//should be
struct bar<F<T,L...>>{

//missing brackets
int main{

//missing semicolon
using toto = T

bar<foo, int,char,char> a;
//should be
bar<foo<int,char,char>> a;
0
Barry On

There's a few syntatic issues here.

  1. bar is a template that takes one type argument. So any partial or explicit specialization of bar must also take one type argument.

    template <template<typename T, typename ...L> class F>
    struct bar<F> {
    

Here, the T and L names are irrelevent, and really you're specializating on a template template. That doesn't match. You'd have to specialize on a specific instantiation of F:

    template <template<typename , typename ...> class F,
        typename T, typename... L>
    struct bar<F<T, L...>> {
  1. You're missing a semicolon:

    using toto = T;
                 ^^
    
  2. Your declaration of main is missing parentheses:

    int main() {
        bar<foo<int,char,char>> a;
    }