What's the essential difference between these two variadic functions?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-24 00:49:09

问题


I've been frustrated by a simple variadic template function:

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

The above doesn't compile, see above linked question and followup for details, yet the following function DOES compile

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"

Both seem to be using the same language mechanism, but why is the first one bad when the second one is good?


回答1:


The difference is that the first function

constexpr size_t num_args () {
    return 0;
}

is not a template, so it can never be called like this

num_args <T...> ();



回答2:


I'm starting to think that the difference is that

foo (args...);

exploits overloading whereas

num_args <T...> ();

exploits specialisation.

Overloading can handle the base case but specialisation can't for function templates (but it can for classes) which is why auxilliary_class<Args...>::value is idiomatic.



来源:https://stackoverflow.com/questions/7111089/whats-the-essential-difference-between-these-two-variadic-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!