开发者

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

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... arg开发者_开发问答s)
{
    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?


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜