Possible Duplicate:
Functions with const arguments and Overloading
I am pretty confused by the overloading and const declaration rules. Here are two things that puzzle me maybe you can help me find the deeper misunderstanding in my head that result in them being puzzling to me. ;)
First issue:
My compiler allows this:
void f(int & x) {
std::cout << "plain f" << std::endl;
}
void f(const int & x) {
std::cout << "const f" << std::endl;
}
But the following causes a compile error (function already has a body):
void f(int x) {
std::cout << "plain f" << std::endl;
}
void f(const int x) {
std::cout << "const f" << std::endl;
}
Which I suppose makes sense because I thought the const was only there to tell the compiler that the object being passed is not changed and in the second case it is copied anyway. But if that is correct then why can I overload functions using const?
In other words, why if I use the compiling version and call the functions like this:
int x1 = 5;
const int x2 = 5;
f(x1);
f(x2);
do I get "plain f" and "const f" instead of "const f" twice? Apparently now I am also using the const to tell the compiler which function to call not only that the reference doesn't change. This gets more confusing because if I remove the "plain" version it works just fine and calls the "const" version twice.
Now what is my actual question? I would like to know what the ideas behind this behavior are because otherwise memorizing it is very hard.
You are correct. Because in the second case it's copied anyway, and so the
const
makes no difference to the caller, the standard defines thatvoid f(const int x)
andvoid f(int x)
have the same signature. Hence they collide, you're trying to define the same function twice.Because in the first case it isn't copied anyway,
void f(const int &x)
andvoid f(int &x)
have different signatures. Hence they overload.In your first case, it's forbidden to call the
int&
version off
withx2
as argument, because that would create a non-const reference to a const object without any explicit cast in sight. Doing that defeats the purpose of the const system (which is that if you want to break const-safety, you have to do so explicitly with a cast). So it makes sense to have const- and non-const overloads of functions with reference parameters.In your second case, there's no relation between the const-ness of the source of a copy, and the const-ness of the destination. You can initialize a const variable from a non-const one, or a non-const one from a const one. This causes no problems and doesn't break const-safety. That's why the standard helpfully makes this clear by defining that your two "different" versions of
f
are actually the same function.n3337 13.1