Dmitry_Milk
> хотя под капотом да, берется адрес
поправка - "хотя под капотом берется адрес, когда l-value значение используется слева от оператора присваивания".
Dmitry_Milk
> не надо путать l-value с адресом
Не надо - это тупо адрес.
Dmitry_Milk
> С точки зрения грамматики тип у самого l-value значения точно такой же, как и
> у r-value значения, а нифига не указатель на такой тип.
Вы сами себя путаете.
Dmitry_Milk
> С точки зрения грамматики тип у самого l-value значения точно такой же, как и у
> r-value значения, а нифига не указатель на такой тип.
Собственно говоря, поэтому в Ц++ и ввели ссылки. Это решило вопрос вполне осмысленным образом: теперь, если "T x", то "x" всегда T&, а далее, смотря по контексту, или каст из T& в T, или каст из T& в const T&, или так и оставить T&.
Другое дело, что:
Delfigamer
> В самом деле - хотели как лучше, а получился
На мой умудрённый опытом взгляд, было ошибкой разрешать делать переменные и члены типа T&, а не только параметры, и разрешать T& как параметр шаблона. Через это приключились многие печали, повлёкшие многие костыли.
Sbtrn. Devil
> На мой умудрённый опытом взгляд
Проще было оставить "переменную как совокупность адреса и значения" как очевидное упрощение простых языков, и не тащить его в "языки, способные к саморазвитию" (каковым и позиционировался C++).
gudleifr
> Проще было оставить "переменную как совокупность адреса и значения" как
> очевидное упрощение простых языков
Ну использование переменных в value-виде это не только в ЯВУ. Возьми, например, интеловский (не AT&T) синтаксис x86 - там тоже пишется синтаксически не "адрес переменной", а сама она
Point struct
x dd ?
y dd ?
Point ends
p Point <>
a dd ?
....
mov eax, a
mov p.x, eaxSbtrn. Devil
> было ошибкой разрешать делать переменные и члены типа T&,
Было ошибкой делать модификаторы ссылочности/изменяемости составной частью типа.
В Ü я такой ошибки не допустил. Тип есть тип, а &/mut/imut - это модификаторы переменных, параметров, полей.
> Через это приключились многие печали, повлёкшие многие костыли.
Ага, как вспомню все эти
std::is_same<std::remove_const<std::remvove_reference<A>>:type, B>::value
Dmitry_Milk
> там тоже пишется синтаксически не "адрес переменной", а сама она
Там вообще нет понятия "переменная". Каждая команда работает с определенным "пространством адресов". Когда непонятно, какая команда (команда, а не тип данных) имеется в виду, используются "уточнители".
Sbtrn. Devil
> Это решило вопрос вполне осмысленным образом: теперь, если "T x", то "x" всегда
> T&, а далее, смотря по контексту, или каст из T& в T, или каст из T& в const
> T&, или так и оставить T&.
Это если грубо и упрощённо, а если по факту - то https://en.cppreference.com/w/cpp/language/value_category
Референсы и категории - это разные понятия в крестах, и там есть целый свод правил о том, как они взаимодействуют.
Delfigamer
> Референсы и категории - это разные понятия в крестах, и там есть целый свод
> правил о том, как они взаимодействуют.
Собственно, это на 95% (и 1% текста) аналогично "грубо и упрощённо":
Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories
…
An lvalue may be used to initialize an lvalue reference;
а оставшиеся 5% (99% текста) - как раз из серии "многих костылей и многих печалей".
Как по мне, раз уж они сделали ссылку полноправным типом, больше нет смысла валять ваньку с этими "категориями", а нужно было идти до конца и делать "типами" всё подряд. Выражение "имя_рантаймовой_переменной_или_члена" - автоматически T&. Выражение, которое возвращает не ссылочный T - автоматически T&& на безымянную переменную, куда ложится результат. "return expr" интерпретировать как "T __result = expr", где __result - эта самая безымянная переменная в вызывающем фрейме. Выражения непосредственно типа T бывают только в случае, если это constexpr.
Кстати, у них был шанс избежать очень многих крестопроблем, введя жёсткое разделение на уровне типов на рантаймовые и constexpr, и назначив литеральным константам constexpr-ные типы const_int и const_string, для которых определены дефолтные конверсии в int и const char *. Но - не сообразили.
Тема в архиве.