Подтвердить что ты не робот

Почему разрешено передавать R-значения по константной ссылке, но не по обычной ссылке?

поскольку заголовок говорит, почему ему разрешено передавать R-значения (литералы) с помощью постоянной ссылки, но не является нормальной ссылкой

void display(const int& a)
{
cout << a ;
}

будет работать, если вызвано display(5), но без const он не будет работать ****** Я имею в виду, как ссылка const должна указывать на значение R (анонимная переменная) *** ***

4b9b3361

Ответ 1

За последний вопрос:

как ссылка константы ссылается на значение R (анонимная переменная)

Вот ответ. Язык С++ говорит, что локальная константная ссылка продлевает время жизни временных значений до конца содержащейся области, но экономит вам стоимость создания копии (т.е. Если вы должны использовать вместо нее локальную переменную).

Ответ 2

Подумайте о каком-либо объекте, как о поле, содержащем какое-то значение внутри, и поле может иметь или не иметь тег имени, т.е. поле с тегом имени variable и поле без тега имени как literal. Есть ли тег имени или нет, у нас есть поле.


Reference - это способ добавления тега имени в наш ящик.

int a = 5;
int &b = a;

у нас есть два тега имени для нашего поля (со значением 5 внутри).

const int &c = 5;

вы есть, ящик был просто назван.


Новое имя поля, у которого никогда не было имени, должно быть отмечено как const. Поскольку значение внутри поля можно изменить с помощью его имени, которое мы не хотим, чтобы это произошло (не разрешено) с нашим literal.

Ответ 3

Возвращается к определению литерала. Литерал является константой; например, значение числа 5 не изменится, хотя переменная может меняться от присвоения значения 5 другому значению. Передача литерала по ссылке подразумевает, что функция может изменить ее, что невозможно сделать по буквам, по определению, поэтому язык требует, чтобы вы изменяли его с помощью константы. Я не думаю, что С++ может модифицировать литералы, даже если он позволяет вам попробовать, но он по-прежнему применяет это соглашение, чтобы напомнить программисту, что буквальное значение не может быть изменено.

Надеюсь, что ответит на ваш вопрос!

Ответ 4

Потому что литералы постоянны. 1 не может стать 2, а "abd" не может стать "edf".

Если С++ разрешил брать литералы с помощью ссылки const, то она либо:

  • Должны позволить литералам изменять их значение динамически, позволяя сделать 1 стать 2.
  • Ожидайте, что программист будет проявлять особую осторожность, чтобы изменять значения только через те ссылки, которые не относятся к литералам, и вызывают поведение undefined, если вы ошибетесь.

(1) создаст хаос в вашей программе, потому что x == 1 может означать, что "равно 2" в зависимости от контекста, и (2) невозможно достичь, потому что как void display(int& a) должно знать, получает литовую ссылку или нет?

Поскольку ни один из этих двух вариантов не имеет смысла, литералы могут передаваться только const.


На самом деле, устаревшее преобразование из строковых литералов в char* является хорошим примером того, почему правила имеют большой смысл, хотя это не ссылка, а указатель. Вам разрешено указывать char* на "abc", но попытка фактически использовать атрибут "изменчивости" char* и изменить один из элементов char приводит к поведению undefined. Это делает все устаревшее преобразование опасным и бесполезным (в коде, не принадлежащем устаревшему).

Вы не хотели бы иметь такие проблемы во всех других частях языка, не так ли?

Ответ 5

Значение r является временным исчезающим объектом, который может быть прочитан, но должен быть уничтожен. Это также значение, которое не может оставаться в левой части задания (как вы могли бы придать значения такому призраку?)

С++ имеет очень специфический способ борьбы с такими типами сущностей. Если вы можете передать r-значение ссылкой (non-const), вы также сможете назначить его изнутри функции. Поэтому правило, что если значения r должны быть переданы по ссылке, это должно быть ссылкой на константу.

Это не вся правда, потому что у вас действительно есть ссылки на r-значение (обозначается &&). Таким образом, вы можете, в конце концов, манипулировать временным объектом, но вам нужно сделать явный оператор, который вы действительно хотите сделать, используя ссылки r-value.