【问题标题】:Help me understand variadic template please请帮我理解可变参数模板
【发布时间】:2011-08-30 18:05:18
【问题描述】:

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

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

【问题讨论】:

    标签: templates c++11


    【解决方案1】:

    我认为您的第一个 printf 重载也必须是模板,但我不是 100% 确定。

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

    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&lt;ARGS&gt; C;,但是所有的对象都是默认构造的,因为你没有将参数传递给要构造的函数。

    【讨论】:

      【解决方案2】:

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

      因为 C++0x 标准不允许你这样做。它不允许您在堆栈上解压缩模板参数。或者进入一个类的数据列表。或任何类似性质的东西。

      它允许您将类型解包到参数列表中,以便函数可以接受可变数量的参数。

      【讨论】:

        猜你喜欢
        • 2016-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-14
        • 2021-11-29
        • 1970-01-01
        • 2012-03-28
        相关资源
        最近更新 更多