12

Is the following perfectly defined by the standard ?

#include <iostream>

template <unsigned int... Values, class... Types>
void f(Types&&... values)
{
    std::cout<<sizeof...(Values)<<" "<<sizeof...(Types)<<std::endl;
}

int main()
{
    f<7, 5>(3);
    return 0;
}

It compiles well under g++ 4.8 but I wonder if it is normal.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • Well I am not good at throwing around standard paragraphs, but why would you not expect that to work? Integrals are valid template parameter values, and type deduction from the arguments is there also for a very long time. – Vinzenz Jan 13 '14 at 21:12
  • As your `Types` are deduced from your function parameters, and your `Values` are specified explicitly, and since `5` is most-definitely *not* a *type*, I have a hard time seeing how this doesn't compile exactly as you have specified (and expected) it should. What would you expect may be a concern of non-standard-compliance? – WhozCraig Jan 13 '14 at 21:15
  • 14
    [temp.param]/11 "A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the *parameter-type-list* of the function template or has a default argument" So I'd say it's legal unless `Types` only appears in non-deduced contexts. – dyp Jan 13 '14 at 21:27

1 Answers1

2

From ISO C++ standard's current working draft 14.1 (11):

A template parameter pack of a function template shall not be followed by another template >parameter unless that template parameter can be deduced from the parameter-type-list of >the function template or has a default argument

In your case 'Types' is a function parameter pack and 'Values', that is a template parameter pack, can be always followed by a function parameter pack. Also this code works for the same reason:

#include <iostream>

template <class... Values, class... Types>
void f(Types&&... values)
{
    std::cout<<sizeof...(Values)<<" "<<sizeof...(Types)<<std::endl;
}

int main()
{
    f<int, float>(-3, 5);
    return 0;
}
Salvatore Avanzo
  • 2,656
  • 1
  • 21
  • 30