Прохождение указателя const по ссылке

Я смущен тем, что следующий код не может скомпилировать

int foo(const float* &a) {
    return 0;
}
int main() {
    float* a;
    foo(a);

    return 0;
}

Компилятор сообщает об ошибке как:

ошибка: неверная инициализация ссылки типа 'const float * &' из выражения типа 'float *'

но когда я пытаюсь передать без ссылки в foo, он компилируется в порядке.

Я думаю, что он должен показывать то же поведение, передаю ли я по ссылке или нет.

Спасибо,

Ответ 1

Потому что это не безопасно для типов. Рассмотрим:

const float f = 2.0;
int foo(const float* &a) {
    a = &f;
    return 0;
}
int main() {
    float* a;
    foo(a);
    *a = 7.0;

    return 0;
}

Любая ссылка или указатель не const обязательно должна быть инвариантной в указанном типе, потому что указатель или ссылка не const поддерживает чтение (ковариантная операция), а также запись (контравариантная операция).

const должен быть добавлен с наибольшего уровня косвенности сначала. Это будет работать:

int foo(float* const &a) {
    return 0;
}
int main() {
    float* a;
    foo(a);

    return 0;
}