我通过一个简单的可变参数模板函数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"
两者似乎都在使用相同的语言机制,但是为什么第二个是好的时候第一个是坏的?
答案 0 :(得分:4)
区别在于第一个功能
constexpr size_t num_args () {
return 0;
}
不是模板,因此永远不会像这样调用
num_args <T...> ();
答案 1 :(得分:0)
我开始认为区别在于
foo (args...);
利用重载而
num_args <T...> ();
利用专业化。
重载可以处理基本情况,但是对于函数模板不能专门化(但它可以用于类),这就是auxilliary_class<Args...>::value
惯用的原因。