Question

So I know it is disallowed to have functions with the same parameters and names:

int a(int b) {
    return b;
}
int a(int b) {
    return b;
}

int main() {
    int c = a(4);
}

This above won't compile. But then I got thinking, what if I passed one by reference, and one by value?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
}

The above does compile, I guess because you can't pass 4 to by reference, so it assumes you want the first a, which means the compiler can distinguish which function you want to call. If I then change main to this:

int main() {
    int c = a(4);
    a(c);
}

It will fail to compile, I assume because c can be passed to either function, so the compiler doesn't know which function to call.

But what about... THIS?

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}

This does compile. Why? I expected it to not, because c can be passed to both the first and second a. Is there some misconception I have?

My question specifically is, how come this (code below) does not compile, and the final one does?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}

If I was the compiler, and I could choose which function to call based how close the parameters matched, for the call a(c), I could choose from both the first and second. Is there any reason that the first or second a cannot be chosen from in this example?

Était-ce utile?

La solution

The process of choosing the correct function to use from a function call is called Overload Resolution. When a function is called, the compiler searches for all functions with that name (overloads) and compiles them into an overload set. Simply put, a best match is chosen by picking the functions that require the least conversions as possible from their parameters.

These are the two functions compiler chooses from a(c):

int a(const int& b);
int a(      int& b);

The second overload is chosen because the first overload requires a const-qualification. The variable with which you called the function with, c, is non-const, so it is a perfect match for the second overload and can be bound to the non-const reference.

Autres conseils

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}

When you call it with a(4) 4 is a literal and only your version taking a const reference can bind it, so that's the one being called.

Now when you call a(c) you got c as a non-const int it will therefore prefer the function taking a non-const reference.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top