简单的可变参数模板功能无法立即实现

spr*_*aff 4 c++ variadic-templates constexpr c++11

我知道sizeof...(Args...)在C++ 0x压缩模板参数列表中产生了类型的数量,但是我想根据其他功能实现它以用于演示目的,但它不会编译.

// This is not a solution -- overload ambiguity.
// template <typename... Args> size_t num_args ();          // Line 7
// template <>
constexpr size_t num_args ()
{
    return 0;
}

template <typename H, typename... T>
constexpr size_t num_args ()                                // Line 16
{
    return 1 + num_args <T...> (); // *HERE*
}

int main ()
{
    std :: cout << num_args <int, int, int> ();
}
Run Code Online (Sandbox Code Playgroud)

这个错误*HERE*

No matching function call to ...
... candidate is template<class H, class ... T> size_t num_args()
Run Code Online (Sandbox Code Playgroud)

即它没有看到首先定义的基本情况.前向声明template<typename...T>num_args();引入了过载分辨率的模糊性.

x.cpp:30:45: note: candidates are:
x.cpp:7:36: note: size_t num_args() [with Args = {int, float, char}, size_t = long unsigned int]
x.cpp:16:9: note: size_t num_args() [with H = int, T = {float, char}, size_t = long unsigned int]
Run Code Online (Sandbox Code Playgroud)

我正在使用gcc 4.6.我怎样才能做到这一点?

谢谢.

Kon*_*lph 7

您没有声明基本案例.你有一个没有模板的num_args函数重载但是当调用一个函数num_args<T...>()时,永远不会找到它,原因很明显:它总是试图实例化一个函数模板.

但是,您可以专门使用功能模板来执行所需的操作.

template <>
constexpr size_t num_args<>()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为在这里你专门研究无参数函数模板,并且这样的模板不存在:你的另一个函数模板num_args总是至少有一个参数,H.

为了真正完成这项工作,您需要部分特化,而这些仅适用于类模板.所以这就是你需要的.

template <typename T>
struct num_args_t;

template <>
struct num_args_t {
    static size_t const value = 0;
};

template <typename H, typename T...>
struct num_args_t {
    static size_t const value = num_args_t<T...>::value + 1;
};

template <typename T...>
constexpr size_t num_args() {
    return num_args_t<T...>::value;
}
Run Code Online (Sandbox Code Playgroud)