Sobrecarga en const y volatile- ¿Por qué funciona por referencia?

Tengo el codigo

#include "stdafx.h"
#include <iostream>

using namespace std;


void func(const int& a)
{
    std::cout << "func(const)" << std::endl;
}

void func(volatile int& a)
{
    std::cout << "func(volatile)" << std::endl;
}

void func(const volatile int& a)
{
    std::cout << "func(const volatile)" << std::endl;
}

int main()
{
    const int a = 0;
    const volatile int b = 0;
    volatile int c = 0;
    func(a);
    func(b);
    func(c);
    system("pause");
    return 0;
}

El código anterior muestra la sobrecarga en función de si los parámetros son constantes / volátiles. Sin embargo, si tuviera que cambiar los parámetros deint& aint, el código ya no se compila y no puedo sobrecargar según los tipos de parámetros const / volatile. No entiendo por qué podemos sobrecargar en base a const y volatile si el int se pasa por referencia, pero no si se pasa por valor.

EDITAR Debo enfatizar Entiendo lo que hace una referencia. No entiendo por qué se permite una sobrecarga de un alias de referencia en const, pero no lo es un int normal.

Respuestas a la pregunta(2)

Su respuesta a la pregunta