为什么这个可变函数模糊不清?

spr*_*aff 3 c++ variadic-templates c++11

这与我之前的帖子有关.我想知道为什么一个尝试的解决方案不起作用.

template <typename... T>             /* A */
size_t num_args ();

template <>
size_t num_args <> ()
{
    return 0;
}

template <typename H, typename... T> /* B */
size_t num_args ()
{
    return 1 + num_args <T...> ();
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试调用,比方说,num_args<int,float>()那么错误是函数调用是不明确的:

  • A与T = {int,float}
  • B,H = int,T = {float}

我不明白这是多么模糊 - A是声明而B是A声明的函数的定义.对吗?

我试图让这个例子起作用,对我之前的问题的回答似乎声称它永远不会起作用.

如果是这样的话,可变自由函数有什么意义呢?有什么可怎么办呢?

R. *_*des 7

我不明白这是多么模糊 - A是声明而B是A声明的函数的定义.对吗?

不是.A是函数模板的声明,B是另一个函数模板的声明(和定义).

编译器无法在两者之间做出决定:它们都没有参数,模板参数与两者都匹配.

中间的那个是A中声明的函数模板的显式全特化.

如果你试图使B成为A的另一个专业化:

template <typename H, typename... T> /* B */
size_t num_args<H, T...>()
{
    return 1 + num_args <T...> ();
}
Run Code Online (Sandbox Code Playgroud)

...你最终会得到一个功能模板的部分特化,这是不允许的.

您可以通过使用具有部分特化的类模板和调用类模板的函数模板的常用技巧来实现此目的:

template <typename... T>
class Num_Args;

template <>
struct Num_Args <>
{
    static constexpr size_t calculate() {
        return 0;
    }
};

template <typename H, typename... T>
struct Num_Args <H, T...>
{
    static constexpr size_t calculate() {
        return 1 + Num_Args<T...>::calculate();
    }
};

template <typename... T> /* B */
constexpr size_t num_args ()
{
    return Num_Args<T...>::calculate();
}
Run Code Online (Sandbox Code Playgroud)