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

时间:2011-08-18 13:27:11

标签: c++ c++11 variadic-templates constexpr

我知道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> ();
}

*HERE*

的错误
No matching function call to ...
... candidate is template<class H, class ... T> size_t num_args()

即。它没有看到首先定义的基本情况。前向声明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]

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

感谢。

2 个答案:

答案 0 :(得分:7)

您没有申报基本案例。你有num_args函数的无模板重载但是在调用函数num_args<T...>()时,这将永远不会被找到,原因显而易见:它总是会尝试实例化一个函数 template

然而,您可以专门化您的功能模板以执行所需的操作。

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

但是,这不起作用,因为在这里你专门研究无参数函数模板而且这样的模板不存在:你的其他函数模板num_args总是至少有一个参数,{{1} }。

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

H

答案 1 :(得分:4)

康拉德的答案应该让你前进,但我认为通常用静态成员常量来表达这种事物的更惯用的方式,所以我只是想提出这个解决方案:

#include <type_traits>

template <typename...> struct arg_size;  // no primary definition needed

template <typename T, typename ...Args> struct arg_size<T, Args...>
  : public std::integral_constant<std::size_t, 1 + arg_size<Args...>::value> { };

template <> struct arg_size<>
  : public std::integral_constant<std::size_t, 0> { };

然后通过arg_size<Args...>::value获得论据包大小。