这两个可变参数函数之间的本质区别是什么?
问题描述:
我通过一个简单的可变参数模板功能已经been frustrated:这两个可变参数函数之间的本质区别是什么?
constexpr size_t num_args() {
return 0;
}
template <typename H, typename... T>
constexpr size_t num_args() {
return 1 + num_args <T...>();
}
int main() {
std :: cout << num_args <int, int, int>();
}
以上不编译,见上面链接的细节问题and followup,但下面的函数编译
template <typename T, typename... Args> void foo (T, Args...);
template <typename... Args> void foo (int, Args...);
void foo() {}
template <typename... Args>
void foo (int x, Args... args)
{
std :: cout << "int:" << x;
foo (args...);
}
template <typename T, typename... Args>
void foo (T x, Args... args)
{
std :: cout << " T:" << x;
foo (args...);
}
foo (int (123), float (123)); // Prints "int:123 T:123.0"
似乎都要使用相同的语言机制,但为什么第二个好的时候第一个不好呢?
答
我开始认为,不同的是,
foo (args...);
漏洞过载而
num_args <T...>();
利用专业化。
重载可以处理基本情况,但专业化不能用于函数模板(但它可以用于类),这就是为什么auxilliary_class<Args...>::value
是惯用的。
答
不同的是,第一个函数
constexpr size_t num_args() {
return 0;
}
不是一个模板,所以它可以永远这样调用
num_args <T...>();
没关系,那不是真的重复,抱歉。 –
请注意'num_args'可以做为sizeof ...(Args)'。 – GManNickG
不错的提示,GMan,谢谢,但是这段代码是为了演示可变参数的语法。 – spraff