The following code compiles:
template<int...>
struct Indices {};
template<int J, int ...I>
void foo(Indices<I...>) {}
int main(int argc, char **argv)
{
foo<2>(Indices<3,4,5>()); //why does this work?
return 0;
}
In the function call, it seems to me that the J parameter becomes 2 and the ...I parameter becomes 3,4,5?
But why does this work? I only specified 2 at foo<2> meaning I specified J as 2 and ...I as nothing. Why can I still specify ...I through the Indices argument? What template mechanism is being used here?
Update: The current answer does not explain why I can have one argument not deduced (explicitly specified) but the others deduced. When exactly does this work? I hope I'm not relying on undefined behavior. Does the standard allow what I'm doing above?
The parameter unpack ...I is deduced by the compiler from the function argument. It is called template argument deduction.
Here are some simple, yet useful examples:
template<typename T>
void f(T const&) {}
f(10); //T is deduced as int
f(10.0); //T is deduced as double
f("10"); //T is deduced as char[3]
Many functions from the standard library are function template, and often the template argument is deduced. Here is one example:
std::vector<int> vi;
std::vector<std::string> vs;
//...
std::sort(vi.begin(), vi.end()); //template argument deduction
std::sort(vs.begin(), vs.end()); //template argument deduction
Here std::sort is a function template but as you can see, we don't explicitly pass the template argument. It is because the template argument is deduced by compiler itself, from the function arguments.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With