请帮我理解变量模板

时间:2011-08-30 18:05:18

标签: templates c++11

这是我在可变参数模板中的第一个代码:

void print_f()
{
}

template<typename 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;
}

当我对print_f(C...);进行递归调用时,究竟发生了什么?我的意思是 模板参数包C得到解压缩,如何在可变参数模板中完成函数参数推导,匹配是如何完成的?

任何人都可以解释一些基础知识吗?

修改:通常在模板类中,如

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

但在可变参数模板中:

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;
}

2 个答案:

答案 0 :(得分:2)

我认为你的第一个printf重载也必须是模板,但我不是百分之百确定。

无论如何,它或多或少都是这样的:

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;

还应该注意,使用您的代码,所有值都出现在同一行,后面跟着许多空行。我想你想在递归之前endl

根据您的编辑:在您的假设函数template<typename T, typename ... ARG> void print_f(const T& a)中,除非您自己指定ARG,否则您将无法调用此函数,因为它无法从函数参数类型中推断出,因为ARG不再位于参数。

此外,无法实例化可变参数模板,因为它们不是类型,它们是一组类型。如果你真的想要实例化一些东西,你可以使用一个元组:std::tuple<ARGS> C;,但是所有的对象都是默认构造的,因为你没有将参数传递给要构造的函数。

答案 1 :(得分:0)

  

并把它放在这里,我们不能这样做,为什么?

因为C ++ 0x标准不允许你。它不允许您解压缩堆栈上的模板参数。或者进入班级的数据列表。或任何那种性质。

它允许您将类型解压缩到参数列表中,以便函数可以获取可变数量的参数。