4

我知道这会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。我怎样才能使这项工作?

谢谢。

4

2 回答 2

8

您没有声明基本情况。你的num_args函数有一个无模板的重载,但是当调用一个函数时num_args<T...>(),它永远不会被发现,原因很明显:它总是会尝试实例化一个函数template

但是,您可以专门化您的函数模板来执行所需的操作。

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

但是,这也行不通,因为您在这里专门设计了一个无参数函数模板,而这样的模板不存在:您的另一个函数模板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;
}
于 2011-08-18T13:32:56.733 回答
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.

于 2011-08-18T13:37:14.193 回答