Почему не неконстантная ссылка на временные объекты?

C ++ позволяет присваивать временные объекты только для константной ссылки. Это не позволит присваивать временные объекты для ссылки.

Например:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

Везде, где я Google для этого результата, я вижу только следующие ответы

  1. Изменение временных объектов может привести к неопределяемым проблемам
  2. Модификация временных объектов опасна
  3. В какой-то момент вы забудете, что это временная переменная

Как уже было сказано, временные объекты исчезают после утверждения. Так что не стоит его модифицировать.

Если C ++ так сильно хочет блокировать изменение временных объектов, он должен был заблокировать чтение временных объектов, верно? Если временный объект исчез, то нет смысла читать содержимое оттуда, верно? Возможные случаи, когда может возникнуть право, могут также включать чтение.

Тогда почему ее блокируют запись в одиночку и позволяют читать?

Пожалуйста, дайте мне твердое объяснение кода C ++.

Пожалуйста, не отклоняйтесь от вопроса, указав несколько альтернатив. Пожалуйста, дайте мне точный ответ с кодом, почему const int & разрешено и int & не допускается для временных объектов.

Один говорит && есть .. мой вопрос другой ..
Иными словами, изменение не будет отражать .. Изменение не будет отражаться, даже если оно постоянно & тоже. Например: удвоить; Const Int & я = а; A ++; не повлияет на меня ..

41

Решение

Первоначальный случай запрета ссылок на временные ссылки был для параметров функции. Предположим, это было разрешено:

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

Почему нет i изменилось?

27

Другие решения

Если C ++ так сильно хочет блокировать изменение временных объектов, он должен был заблокировать чтение временных объектов, верно? Если временный объект исчез, то нет смысла читать содержимое оттуда, верно?

Нет, чтение объекта совершенно разумно. То, что в будущем оно исчезнет, ​​не означает, что данные будут прочитаны. сейчас бессмысленно.

open_file(std::string("foo.txt"));

std::string("foo.txt") является временным, который прекратит существовать после вызова open_file() но данные, которые он содержит, хотя и существуют, имеют большое значение.

Рациональное использование запрета привязки временных файлов к неконстантным ссылкам на самом деле не является фундаментальной проблемой при записи во временные ссылки. На самом деле во многих местах C ++ очень рад разрешить изменение временных значений:

std::string("foo") = "bar";

Просто разработчики посчитали, что это вызовет достаточное количество проблем (возможно, из-за общей идиомы «параметров») без включения чего-либо аналогичного значения, поэтому они просто приняли проектное решение, чтобы запретить временные привязки к неконстантным Рекомендации.

С помощью ссылок на rvalue вы можете делать то, что раньше было запрещено:

void foo(int &&output) {
output = 1;
}

foo(2);

Это отлично работает, просто не очень полезно.

9

Если у вас есть временный объект, который очень дорого копировать, вы можете взять const& к этому объекту (скажем, возврат функции), а не копировать его в другую переменную для использования позже. Постоянное обращение к временному объекту продлевает срок службы этого временного объекта до тех пор, пока действует ссылка, что позволяет получить доступ к любому читаемому состоянию.

Запись запрещена, потому что, как только вы захотите изменить переменную, у вас также может появиться реальный экземпляр, а не временный, имеющий псевдоним только как неконстантную ссылку.

3

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

String& a = String("test");         // Error

Вы хотите ссылку. Ссылка относится к объекту, на который она ссылается. Как и адрес объекта (хотя ссылки не являются адресами, это делает объяснение более понятным). Вы на самом деле пытаетесь получить что-то вроде адреса String("test"), Но этот объект исчезнет прямо на следующей строке, так какой смысл в его адресе, если объект, на который он указывает, не существует? a сейчас указывает на что-то бессмысленное …

Что касается вашего второго вопроса, какой смысл вообще разрешать временные объекты, ну, в этом нет ничего плохого. Рассмотрим, например, случай, когда вы хотите передать String объект функции, которая возвращает, скажем, измененную строку, соответствующую этой строке. Давайте вызовем функцию DoubleString, поэтому вместо того, чтобы делать

String s("hello ");
String s2 = DoubleString(s);

Вы можете использовать более короткую, более удобную форму

String s2 = DoubleString(String("hello "));

Видите, временный объект String("hello ") выживает всю строку кода, что означает, что он не поврежден при отправке DoubleString и после этого. Он уничтожается только после завершения всей линии.

1
По вопросам рекламы [email protected]