Consider the following code snippet:
template<class T>
std::enable_if_t<std::is_integral<T>::value, bool> func(T value) {
std::cout << "T\n";
return func(static_cast<int64_t>(value));
}
bool func(int64_t value) {
std::cout << "int64_t\n";
return true;
}
int main() {
func(1);
}
It causes infinite recursion. However, swapping the definition order of these two functions (if bool func(int64_t value)
defined before template one) helps to avoid this issue.
Why is that? Does order of function overloads matter?
Does order of function overloads matter?
It doesn't change the result of overload resolution, but the result of name lookup; which happens before overload resolution.
(emphasis mine)
For a name used in global (top-level namespace) scope, outside of any function, class, or user-declared namespace, the global scope before the use of the name is examined:
That means for the invocation of func
inside the templated func
, only itself could be found (and be added to the overload set), the non-template version won't be considered at all.
As you have seen, if you change their declaration order, both func
would be found and considered at the following overload resolution, and the non-template func
is selected (as expected).
When the compiler is parsing the first function (the template) it doesn't know anything about the second overload of func
. Parsing is done top-to-bottom of the source file.
That's the reason you need to have declarations of symbols before you use them. That also means just having a declaration of bool func(int64_t);
at the top would solve your problem.
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