c++ - Perplexing non-trailing parameter pack behaviour -


i've come across interesting variadic template function behaviour. can point out relevant rules in standard define this?

gcc, icc , msvc compile following code (clang doesn't, understand due compiler bugs).

template<class a, class... bs, class c> void foo(a, bs..., c) { }  int main() {     foo<int, int, int, int>(1, 2, 3, 4, 5); } 

in call foo, template arguments provided a , bs, c deduced int.

however, if flip last 2 template parameters:

template<class a, class c, class... bs> void foo(a, bs..., c) { } 

then all three compilers throw errors. here 1 gcc:

main.cpp: in function 'int main()': main.cpp:8:42: error: no matching function call 'foo(int, int, int, int, int)'      foo<int, int, int, int>(1, 2, 3, 4, 5);                                           ^ main.cpp:4:6: note: candidate: template<class a, class c, class ... bs> void foo(a, bs ..., c)  void foo(a, bs..., c) { }       ^~~ main.cpp:4:6: note:   template argument deduction/substitution failed: main.cpp:8:42: note:   candidate expects 4 arguments, 5 provided      foo<int, int, int, int>(1, 2, 3, 4, 5);                                       ^ 

to make things more interesting, calling 4 arguments invalid first foo, , valid second.

it seems in first version of foo, c must deduced, whereas in second, c must explicitly supplied.

what rules in standard define behaviour?

as case, answer came me few hours after posted question.

consider 2 versions of foo:

template<class a, class... bs, class c> void foo1(a, bs..., c) { }  template<class a, class c, class... bs> void foo2(a, bs..., c) { } 

and following call (assuming foo foo1 or foo2):

foo<int,int,int,int>(1,2,3,4,5); 

in case of foo1, template parameters picked follows:

a = int (explicitly provided) bs = {int,int,int} (explicitly provided) c = int (deduced) 

but in case of foo2 this:

a = int (explicitly provided) c = int (explicitly provided) bs = {int,int} (explicitly provided) 

bs in non-deduced context ([temp.deduct.type]/5.7), further function arguments can not used extend pack. such, foo2 must have it's template arguments explicitly provided.


Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -