Необъяснимое поведение функции, принимающей универсальную ссылку и возвращающую ссылку на константу
Я всегда думал, что следующая функция, которая принимает универсальную ссылку, должна возвращать константу-ссылку.
template <typename T>
const T& Const(T&& val)
{
return val;
}
Однако следующий код успешно компилируется с VS C++ и gcc:
int x = 5;
Const(x) = 6;
Значение переменной x равно 6 после запуска. Таким образом, функция Const возвращает неконстантную ссылку.
Чтобы получить ошибку компилятора, функция Const должна быть изменена, чтобы принять стандартную ссылку l-value или объявить как возвращающую const std::remove_reference_t<T>&
.
Это почему? Какое правило я пропустил? Заранее спасибо!
Ответы
Ответ 1
универсальная ссылка
Нет, они называются "справочными ссылками". Термин "универсальная ссылка" устарел.
Это почему?
Когда вы вызываете Const(x)
, x
является lvalue, поэтому T
выводится как int&
. Тогда ваш тип возврата будет:
-
const T & = T const &
→ int & const &
→ int &
int & const &
является ссылкой на const
ссылку на int
которая является такой же, как int&
. (В этом случае const
применяется к int&
, а не только к int
, как T = int&
).