Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling variadic argument function from template class

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.

like image 239
ds1848 Avatar asked Apr 02 '12 05:04

ds1848


People also ask

How do you access Variadic arguments?

To access variadic arguments, we must include the <stdarg. h> header.

What is Variadic template C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

Is printf Variadic function?

Variadic functions are functions (e.g. printf) which take a variable number of arguments.

How do you expand a parameter pack?

Parameter packs can only be expanded in a strictly-defined list of contexts, and operator , is not one of them. In other words, it's not possible to use pack expansion to generate an expression consisting of a series of subexpressions delimited by operator , .


1 Answers

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.

like image 189
Johannes Schaub - litb Avatar answered Oct 16 '22 23:10

Johannes Schaub - litb