Variadic模板功能:专门的头/尾和空基座

时间:2013-03-23 00:37:34

标签: c++ templates c++11 variadic-templates template-meta-programming

我想在类中使用可变参数模板函数。可变参数模板参数是字符,应该以类似循环的方式处理。所以我想把它写成haskell,头/尾分裂列表,直到达到基本情况(空列表)。

作为一个例子,让我们只计算给出的参数数量(只是一个最小的例子)。

我想出了以下代码:

struct MyClass {
    template<char ...X>
    static int count();
};


template<>
int MyClass::count<>() {
    return 0;
}
template<char Head, char ...Tail>
int MyClass::count<Head, Tail...>() {
    return 1 + count<Tail...>();
}

但是,doesn't seem to work

prog.cpp:12:35: error: function template partial specialization ‘count<Head, Tail ...>’ is not allowed
prog.cpp:12:5: error: prototype for ‘int MyClass::count()’ does not match any in class ‘MyClass’
prog.cpp:3:16: error: candidate is: template<char ...X> static int MyClass::count()

我怎样才能做到这一点?我知道功能不支持部分特化。但我认为将变量模板专门设计为头/尾和空基本案例版本不是部分专业化,而是完整专业化,但也许我错了?我是否需要将其写为类而不是函数?

我找到了一些示例(printf),它们实现了一个基本案例而根本没有使用模板语法。但我想我的情况有所不同,因为对printf的调用不使用模板语法而是使用类型演绎,所以printf(tail...)调用printf()如果tail是空。另一方面,就我而言,在调用基本案例时,count<>()count()不同。

1 个答案:

答案 0 :(得分:18)

我想说重载函数模板通常是一个更好的主意,而不是专门化它们:

struct MyClass {
    template<typename... Tail>
    static int count() {
        return 0;
    }

    template<char Head, char... Tail>
    static int count() {
        return 1 + count<Tail...>();
    }
};

#include <iostream>

int main() {
    std::cout << MyClass::count<'f','o','o'>();
}

这是一个live example。我还要提到内置运算符sizeof...可用于此目的:

struct MyClass {
    template<char... Chars>
    static int count() {
        return sizeof...(Chars);
    //         ^^^^^^^^^
    }
};