Por que os qualificadores const em argumentos de função são usados ​​para sobrecarregar a resolução? [duplicado]

Duplicata Possível:
Funções com argumentos const e Sobrecarga

Estou muito confuso com as regras de sobrecarga e declaração const. Aqui estão duas coisas que me confundem, talvez você possa me ajudar a encontrar um mal-entendido mais profundo na minha cabeça, o que faz com que eles fiquem confusos comigo. ;)

Primeira edição:

Meu compilador permite isso:

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

Mas o seguinte causa um erro de compilação (a função já possui um corpo):

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

O que eu acho que faz sentido porque eu pensei que a const estava lá apenas para dizer ao compilador que o objeto que está sendo passado não é alterado e no segundo caso ele é copiado de qualquer maneira. Mas se isso está correto, então por que eu posso sobrecarregar as funções usando const?

Em outras palavras, por que se eu usar a versão de compilação e chamar as funções assim:

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

obtenho "plain f" e "const f" em vez de "const f" duas vezes? Aparentemente, agora eu também estou usando o const para dizer ao compilador qual função chamar não apenas que a referência não muda. Isso fica mais confuso porque, se eu remover a versão "simples", ela funciona bem e chama a versão "const" duas vezes.

Agora, qual é a minha pergunta atual? Eu gostaria de saber quais são as idéias por trás desse comportamento porque, de outra forma, memorizá-lo é muito difícil.

questionAnswers(2)

yourAnswerToTheQuestion