首页 > 解决方案 > 不带参数的可变模板函数

问题描述

我想编写一个函数,它将根据函数的类型而不是参数进行操作。因此,该函数不接收基于模板的参数。一般要点是这样的:

#include <iostream>

void func() {
    std::cout<<"End marker\n";
}

template <typename Type, typename... T>
void func() {
    std::cout<<"Type sizeof "<<sizeof(T)<<"\n";

    func<T...>();
}

int main() {
    func<int, int, int>();
}

当然,这不会编译。我试过这样做:

template <typename Type, typename... T>
void func() {
    std::cout<<"Type sizeof "<<sizeof(T)<<"\n";

    if( sizeof...(T)!=0 )
        func<T...>();
}

但是,这不起作用。可能不会被func<T...>评估,但它确实需要是可编译的。

有没有办法做到这一点,我错过了?

标签: c++templatesvisual-c++variadic-templatesspecialization

解决方案


您可以将非模板函数func变成接受零模板参数的可变参数模板函数。然后在参数个数不为零时让 SFINAE 移走这个模板函数。

以下应该工作:

#include <iostream>
#include <type_traits>

template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == 0>::type func() {
    std::cout<<"End marker\n";
}

template <typename T, typename... Ts>
void func() {
    std::cout << "Type sizeof " << sizeof(T) << "\n";

    func<Ts...>();
}

int main() {
    func<int, int, int>();
}

但是,请注意:

(8) 可以在任何实例化之前检查模板的有效性。[注意:知道哪些名称是类型名称允许以这种方式检查每个模板的语法。— 尾注] 如果:[..] (8.3) 可变参数模板的每个有效特化都需要一个空模板参数包...

来源在这里

更新

这也可以:

#include <iostream>
#include <type_traits>

void func() {
    std::cout<<"End marker\n";
}

template <typename T, typename... Ts>
void func() {
    std::cout << "Type sizeof " << sizeof(T) << "\n";

    if constexpr (0 == sizeof...(Ts))
        func();
    else
        func<Ts...>();
}

int main() {
    func<int, int, int>();
}

推荐阅读