Ответ 1
Добро пожаловать в const и справку рушится. Когда у вас есть const T&
, ссылка применяется к T
, как и const
. Вы называете g
как
g<int&>(n);
так что вы указали, что T
является int&
. Когда мы применяем ссылку на ссылку lvalue, две ссылки сворачиваются в одну, поэтому int& &
становится просто int&
. Затем мы получаем правило из [dcl.ref]/1, которое гласит, что если вы применяете const
к ссылке, она отбрасывается, поэтому int& const
просто становится int&
(обратите внимание, что вы не можете фактически объявить int& const
, он должен приходят из typedef или шаблона). Это значит для
g<int&>(n);
ты на самом деле звонишь
void f(int& a, int& b)
и вы на самом деле не изменяете константу.
Если бы вы назвали g
как
g<int>(n);
// or just
g(n);
тогда T
будет int
, а f
будет выбито как
void f(int a, const int& b)
Поскольку T
больше не является ссылкой, к ней применяются const
и &
, и вы бы получили ошибку компилятора за попытку изменить постоянную переменную.