提问者:小点点

递归模板包


我遇到了递归模板包解包的麻烦。 我目前拥有的是:

template<T> 
constexpr void register_types() {
    do_something<T>();
    return;
}

template <class T, T2, class... Args> 
constexpr void register_types() {
    do_something<T>();
    register_types<T2, Args...>();
}


int main(int argc, char** argv) {
    register_types<unsigned char, unsigned short, unsigned int, unsigned long long int>();

但是我想要一个更空的基本情况,比如

template<> 
constexpr void register_types() {
    return;
}

template <class T, class... Args> 
constexpr void register_types() {
    do_something<T>();
    register_types<Args...>();
}

然而,这给了我一个错误:

src/benchmarks/benchmark_main.cc:68:31:错误:“register_types”不是模板函数

有可能有一个空的参数包作为基本情况吗? 我看过这篇文章,但如果可能的话,我想避免使用SFINAE。


共3个答案

匿名用户

有可能有一个空的参数包作为基本情况吗?

不能在没有模板参数的情况下声明模板函数。

但是您可以声明一个接受空模板参数列表的模板函数(使用默认值/类型或variadics)。

对于您的案例建议:尝试使用

template <int = 0> 
constexpr void register_types() {
    return;
}

template <class T, class... Args> 
constexpr void register_types() {
    do_something<T>();
    register_types<Args...>();
}

这样,地面情况(第一个)是一个常规模板函数,接受零模板参数(感谢默认值)。

接受整数而不是类型,当args...不为空时不会给您带来冲突问题。

匿名用户

是的,您可以编写一个空的基用例来终止递归(尽管您仍然需要模板参数)。

但是,如果只使用折叠表达式,就可以避免自己实现其中的任何一个:

template <class ...Ts> 
constexpr void register_types() {
    (do_something<Ts>(), ...);
}

这是一个演示。

匿名用户

否,您不能使用空模板参数。 如果这对你的案子有帮助,我不反对。 您可以使用一个类来存储多个函数的typename。