Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload resolution, order of defined functions and templates

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?

like image 787
pure cuteness Avatar asked Mar 12 '19 10:03

pure cuteness


2 Answers

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).

like image 110
songyuanyao Avatar answered Sep 26 '22 02:09

songyuanyao


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.

like image 29
Some programmer dude Avatar answered Sep 26 '22 02:09

Some programmer dude