поскольку заголовок говорит, почему разрешено передавать R-значения (литералы) по постоянной ссылке, но не по обычной ссылке
void display(const int& a)
{
cout << a ;
}
будет работать, если называется display(5)
но без const
это не сработает ****** Я имею в виду, как можно const
ссылка продолжает указывать на R-значение (анонимная переменная) ******
Для вашего последнего вопроса:
как ссылка на const может указывать на R-значение (анонимная переменная)
Вот ответ. Язык C ++ говорит, что локальная ссылка на const продлевает время жизни временных значений до конца содержащейся области, но экономит затраты на конструкцию копирования (т.е. если вы вместо этого используете локальную переменную).
Думайте о любом объекте как о коробка содержащее некоторое значение внутри, и поле может иметь или не иметь тег имени, то есть поле с имя тега как variable
и коробка без имя тега как literal
, Есть ли имя тега или нет, у нас есть коробка.
Reference
это способ, которым мы добавляем имя тега в нашу коробку.
int a = 5;
int &b = a;
у нас есть два именные бирки для нашей коробки (со значением 5
внутри).
const int &c = 5;
Вот, пожалуйста, коробка была названа.
Новое имя ящика, у которого никогда не было имени, должно быть помечено как const
, Потому что значение внутри поля может быть изменено через его имя, которое мы не хотим, чтобы это произошло (не допускается) нашим literal
коробка.
Это возвращается к определению буквального. Литерал — это константа; например, значение числа 5 никогда не изменится, хотя переменная может измениться от присвоения значения 5 другому значению. Передача литерала по ссылке подразумевает, что функция может изменить его, что по определению вы не можете сделать с литералом, поэтому язык требует, чтобы вы изменили его с помощью const. Я не думаю, что C ++ мог бы модифицировать литералы, даже если бы он позволил вам попробовать, но он все еще применяет это соглашение, чтобы напомнить программисту, что буквальное значение не может быть изменено.
Надеюсь это ответит на твой вопрос!
Потому что литералы постоянны. 1 не может стать 2, и "abd"
не может стать "edf"
,
Если C ++ позволяет вам принимать литералы неconst
ссылка, то это будет либо:
(1) создаст хаос в вашей программе, потому что x == 1
может означать «равен х равен 2» в зависимости от контекста, и (2) невозможно достичь, потому что как void display(int& a)
должен знать, получает ли он буквальную ссылку или нет?
Поскольку ни один из этих двух вариантов не имеет смысла, литералы могут быть переданы только const
Рекомендации.
На самом деле, устаревшее преобразование из строковых литералов в char*
хороший пример того, почему правила имеют большой смысл, хотя это не ссылка, а указатель. Вы можете позволить char*
указать на "abc"
, но попытка фактически использовать атрибут «модифицируемости» char*
и изменить один из char
элементы приводят к неопределенному поведению. Это делает все устаревшее преобразование как опасным, так и бесполезным (в устаревшем коде).
Вы не хотели бы иметь такие проблемы во всех других частях языка, не так ли?
Значение r — это временно исчезающий объект, который можно прочитать, но он скоро будет уничтожен. Это также значение, которое не может оставаться в левой части присваивания (как вы могли бы иметь смысл присваивать значения такому призраку?)
C ++ имеет очень специфический способ работы с такими объектами. Если бы вы могли передать значение r по (неконстантной) ссылке, вы также могли бы присвоить его изнутри функции. Поэтому правило, что если r-значения должны передаваться по ссылке, это должна быть константная ссылка.
Это не вся правда, потому что у вас есть, действительно, r-значение ссылки (обозначается &&
). Таким образом, вы можете, в конце концов, манипулировать временным объектом, но вы должны сделать явное утверждение, которое вы действительно хотите сделать, используя ссылки на r-значение.