Template deduction fails with argument after param

2019-07-04 10:39发布

问题:

I have this function:

template <typename... Args>
void f(Args... args, int last)
{
}

Template deduction fails if I call it without explicit template parameters:

f(2, 2); // candidate expects 1 argument, 2 provided

But giving the explicit template parameters for the parameter pack works:

f<int>(2, 2); // compiles fine

Even though logically speaking, the compiler should be able to deduce that the parameter pack consists of all but the last argument types. How would I fix this?

回答1:

[temp.deduct.type]/p5:

The non-deduced contexts are:

  • [...]
  • A function parameter pack that does not occur at the end of the parameter-declaration-list.

To get deduction, you'll have to do

template <typename... Args>
void f(Args... args)
{
}

and slice off the last argument in the body, or make last first instead:

template <typename... Args>
void f(int first, Args... args)
{
}

It's hard to give more specific advice since we don't know what this function template is supposed to do.



回答2:

From [temp.deduct.type]:

The non-deduced contexts are:
[...] — A function parameter pack that does not occur at the end of the parameter-declaration-list.

Your parameter pack, args, is a non-deduced context since it's not the last parameter. Non-deduced contexts, like the name suggests, cannot be deduced - which leads to a template deduction failure.

When you explicitly provide the template parameters (via f<int>(2, 2)), no deduction has to take place, so the code is fine, you are simply explicitly calling f<int>(int, int).