5
votes

I have a template class with a variadic template member function that I am not able to call from outside the class. This a simplified example of what I am trying to do:

template<typename T>
struct foo{
    foo(){}

    template<int... I>
    int run(){
        return sizeof...(I); // or whatever
    }
};

template<int... I>
int run_int(){
    return foo<int>().run<I...>();  // OK
}

template<typename T, int... I>
int run_T(){
    return foo<T>().run<I...>(); // error
}

When foo is specialized, I can call its template member function run() with no problems. But if I try to call it from a function or structure that does not specialize foo, gcc(4.7) issues an error saying "parameter packs not expanded with ‘...’ ". I tried the same thing with clang (3.1) but got a similar error ( " error: expression contains unexpanded parameter pack 'I' " ).

Can anyone help me understand why the last function fails to compile? For now I can get around it by making "int...I" a non-type parameter of foo itself, and then call it like this from outside:

 foo<T, I...>().run()

but I am still puzzled as to why it does not compile the other way.

1
foo<T>().template run<I...>() - Luc Danton
@LucDanton: You should post that as the answer. Here is a quote of the rule: When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object or pointer expression of the postfix-expression or the nested-name-specifier in the qualified-id depends on a template parameter (14.6.2) but does not refer to a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. - Jesse Good

1 Answers

6
votes

Going to collect rep...

foo<T>().template run<I...>();

See Where and why do I have to put the "template" and "typename" keywords? for why the template keyword is needed.