Suppose I have this program:
#include <iostream>
int fun(...) {return 0;}
template <typename... Args>
int fun(const Args&...) {return 1;}
int fun(const double val) {return 2;}
int main()
{
std::cout << fun(1,2,3) << fun(1) << fun(1.0);
return 0;
}
This program returns the following:
112
I understand why fun(1.0)
would return 2
, as that's the closest matching function candidate, but why do the first 2 examples return 1
?
This page (http://en.cppreference.com/w/cpp/language/overload_resolution) provides a reference of function overloading rules, but seems to stop short of covering variadics. Where can I find out the rules for overloading of variadic / template variadic functions?
why do the first 2 examples return
1
?
A C-style variadic function is always the worst match (technically speaking it involves an "ellipsis conversion sequence" which is worse than any standard or user-defined conversion sequence). For fun(1, 2, 3)
, with the variadic function template, deduction is performed as usual giving Args
= int
, int
, int
. This is an exact match.
For fun(1)
the variadic function template wins again because Args
is deduced as int
and once again we have an exact match, which is better than the floating-integral conversion required to call fun(double)
.
Where can I find out the rules for overloading of variadic / template variadic functions?
The page you linked already covers what you need to know about C-style variadic functions:
1) A standard conversion sequence is always better than a user-defined conversion sequence or an ellipsis conversion sequence.
2) A user-defined conversion sequence is always better than an ellipsis conversion sequence
For variadic templates there aren't really any special rules; template parameter deduction is performed as usual and then the usual overload resolution rules are applied.
The rules get more complicated in a case like this:
template <class... Args> int f(Args...) { return 1; }
template <class T> int f(T) { return 2; }
f(1); // returns 2
In this case the usual rules can't resolve the overload, but the second function is selected because it's "more specialized". The rules for determining when one function template is more specialized than another are (in my opinion) very hard to understand. You can find them at §14.5.6.2 [temp.func.order] in the C++11 standard.
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