Some background:
I came across something the other day that got me thinking about overload resolution in nested function calls. Consider the code below:
#include <iostream>
void printer(const int &a)
{
std::cout << a << "\n";
}
const int& func(const int &a)
{
std::cout << "const int& ";
return a;
}
int& func(int &a)
{
std::cout << "int& ";
return a;
}
int main()
{
int a = 42;
const int b = 21;
printer(func(a));
printer(func(b));
return 0;
}
This code prints
int& 42
const int& 21
So, obviously func(a) sees that a is a non-const int. The compiler must also see that the printer function wants a const int& argument. And there exists a func(…) that returns a const int&. I looked into the C++ standard and it says that const refs and refs are considered distinct parameter types (and that is why it picks the int& for func(a)).
To the question:
Is the compiler allowed to use the func(const int &) version instead of the func(int&) when calling func(a)?
(Perhaps there is some kind of optimization possibility if it sees that the result is passed to a function wanting a const int& parameter.)
Overload resolution does not consider the return type. That is, it will only look at the argument to the function and the different overloads, disregarding how the returned value is going to be used.
For a more explicit test, consider changing the non-const overload to:
which will fail to compile, even if there is a different similar overload that would allow the code to compile.