开发者

Help me understand variadic template please

Here is my first code in variadic templates :

void print_f()
{
}

template<ty开发者_Python百科pename T, typename ... ARG>
void print_f(const T& a, ARG... C)
{
    std::cout<<a;
    print_f(C...); // -> at this line I want to know
    std::cout<<std::endl;
}

when I make a recursive call to print_f(C...); , what actually happens? what I mean is template parameter pack C gets unpacked and how is function argument deduction is done in variadic templates , how is matching done?

can anyone please explain some basics?

Edit: Usually in template class like

template <typename T> class x{
public:
T aa; // can declare variable of type T
};

but in variadic templates :

template<typename T, typename ... ARG>
void print_f(const T& a /* , ARG... C -> if remove this */ )
{
    std::cout<<a;
    ARG... C // and put it here , we can't do this,  why?
    print_f(C...); 
    std::cout<<std::endl;
}


I think your first printf overload must also be a template, but I'm not 100% sure.

Anyway, it works more or less like this:

printf("APPLE", 10, '@', 9.0); 
// this calls printf(const char*, int, char, double)
// with T=const char*, and ARG={int, char, double}
    printf(const char* a, ARG ... C) {
    std::cout<<a; // this displays "APPLE"
    print_f(C...); 
    // this calls printf(int, char, double)
    // with T=int, and ARG={char, double}
        printf(int a, ARG ... C) {
        std::cout<<a; // this displays 10
        print_f(C...); 
        // this calls printf(char, double)
        // with T=char, and ARG={double}
            printf(char a, ARG ... C) {
            std::cout<<a; // this displays '@'
            print_f(C...); 
            // this calls printf(double)
            // with T=double, and ARG={}
                printf(double a, ARG ... C) {
                std::cout<<a; // this displays 9.0
                print_f(C...); 
                // this calls printf()
                    printf() {
                    }
                std::cout<<std::endl;
            std::cout<<std::endl;
        std::cout<<std::endl;
    std::cout<<std::endl;

It should also be noted that with your code, all the values appear on the same line, followed by lots of blank lines. I think you wanted the endl before the recursion.

As per your edit: In your hypothetical function template<typename T, typename ... ARG> void print_f(const T& a), you would be unable to call this function unless you specified ARG yourself, as it cannot be deduced from the function parameter types, since ARG is no longer in the parameters.

Also, variadic templates cannot be instantiated because they are not a type, they are a grouping of types. If you really wanted to instantiate something, you could use a tuple: std::tuple<ARGS> C;, but all the objects would be default constructed, since you didn't pass parameters to the function to construct from.


and put it here , we can't do this, why?

Because the C++0x standard does not let you. It doesn't allow you to unpack template parameters on the stack. Or into a class's data list. Or anything of that nature.

It allows you to unpack the types into a parameter list, so that a function can take a variable number of parameters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜