我最初有以下递归可变参数模板代码
#include <functional>
#include <iostream>
// end of recursion
void apply(std::function<void()> f, int)
{
f();
}
// base recursive
template <typename Head, typename ...Tail>
void apply(std::function<void(Head, Tail...)> f, int i)
{
auto g = [=](Tail&& ...args)
{
f(i, std::forward<Tail>(args)...);
};
apply(std::function<void(Tail...)>{g}, ++i);
}
void foo(int a, int b, double c, int d)
{
std::cout << a << b << c << d << std::endl;
}
int main()
{
auto f = std::function<void(int, int, double, int)>(foo);
apply(f, 0);
}
它工作正常,但我不得不为Head = double添加一个案例,所以我最终使用了部分特化结构
#include <functional>
#include <iostream>
// base recursive case
template <typename Head, typename ...Tail>
struct Apply {
static void apply(std::function<void(Head, Tail...)> f, int i)
{
auto g = [=](Tail&& ...args)
{
f(i, std::forward<Tail>(args)...);
};
Apply<Tail...>::apply(std::function<void(Tail...)>{g}, ++i);
}
};
// specialization case for double
template <typename ...Tail>
struct Apply<double, Tail...> {
static void apply(std::function<void(double, Tail...)> f, int i)
{
auto g = [=](Tail&& ...args)
{
f(777.0, std::forward<Tail>(args)...);
};
Apply<Tail...>::apply(std::function<void(Tail...)>{g}, ++i);
}
};
// end of recursion
template <>
struct Apply {
static void apply(std::function<void()> f, int)
{
f();
}
};
void foo(int a, int b, double c, int d)
{
std::cout << a << b << c << d << std::endl;
}
int main()
{
auto f = std::function<void(int, int, double, int)>(foo);
Apply<int, int, double, int>::apply(f, 0);
}
但我似乎无法想出正确的#34;结束递归&#34;结构的版本,当它被称为Apply<Tail...>::apply(std::function<void(Tail...)>{g}, ++i);
时,Tail...
为空。
声明结构的方式 - template <typename Head, typename ...Tail>
- 它需要至少有一种类型,因此它不能为空,我不能结束递归,因为那。但是我也无法解除这个要求,因为我需要一种方法来引用Tail...
方法中的第一个类型(即apply
)。
答案 0 :(得分:1)
提供允许空专业化的主模板。
template <typename ...Types>
struct Apply;
现在提供两个部分特化:
template <typename ... Tail>
struct Apply<double, Tail...>
{
...
};
template <typename Head, typename ... Tail, typename = std::enable_if_t<!std::is_same<Head, double>::value>>
struct Apply<Head, Tail...>
{
...
};
最后,空专业化:
template <>
struct Apply<>
{
...
};