¿Por qué se utilizan los calificadores const en los argumentos de función para la resolución de sobrecarga? [duplicar]

Posible duplicado:
Funciones con argumentos const y sobrecarga.

Estoy bastante confundido por las reglas de sobrecarga y declaración de const. Aquí hay dos cosas que me desconciertan. Quizás puedas ayudarme a encontrar un malentendido más profundo en mi cabeza que haga que me confundan. ;)

Primer problema:

Mi compilador permite esto:

void f(int & x) {
  std::cout << "plain f" << std::endl;
}
void f(const int & x) {
  std::cout << "const f" << std::endl;
}

Pero lo siguiente provoca un error de compilación (la función ya tiene un cuerpo):

void f(int x) {
  std::cout << "plain f" << std::endl;
}
void f(const int x) {
  std::cout << "const f" << std::endl;
}

Lo cual supongo que tiene sentido porque pensé que la constante solo estaba allí para decirle al compilador que el objeto que se está pasando no se cambia y en el segundo caso se copia de todos modos. Pero si eso es correcto, entonces ¿por qué puedo sobrecargar las funciones usando const?

En otras palabras, ¿por qué si uso la versión de compilación y llamo a las funciones de esta manera?

  int x1 = 5;
  const int x2 = 5;
  f(x1);
  f(x2);

¿Me sale "plain f" y "const f" en lugar de "const f" dos veces? Aparentemente ahora también estoy usando la constante para decirle al compilador a qué función llamar, no solo que la referencia no cambia. Esto se vuelve más confuso porque si quito la versión "normal" funciona bien y llamo a la versión "const" dos veces.

Ahora, ¿cuál es mi pregunta real? Me gustaría saber cuáles son las ideas detrás de este comportamiento porque, de lo contrario, memorizarlo es muy difícil.

Respuestas a la pregunta(2)

Su respuesta a la pregunta