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
Post a Comment