Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are const qualifiers in function arguments used for overloading resolution? [duplicate]

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.

like image 914
Sarien Avatar asked Jul 25 '12 08:07

Sarien


1 Answers

n3337 13.1

[ Note: As specified in 8.3.5, function declarations that have equivalent parameter declarations declare the same function and therefore cannot be overloaded: ffer only in the presence or absence

— Parameter declarations that di3 of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called. [ Example:

typedef const int cInt;
int f(int);
int f(const int); // redeclaration of f(int)
int f(int) { /* ... */ } // definition of f(int)
int f(cInt) { /* ... */ } // error: redefinition of f(int)

— end example ] Only the const and volatile type-specifiers at the outermost level of the parameter type specifica- tion are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations.124 In particular, for any type T, “pointer to T,” “pointer to const T,” and “pointer to volatile T” are considered distinct parameter types, as are “reference to T,” “reference to const T,” and “reference to volatile T.”

like image 123
ForEveR Avatar answered Nov 15 '22 19:11

ForEveR