Неправильная форма:
int &z = 12;
Правильная форма:
int y;
int &r = y;
Вопрос :
Почему первый код неправильный? В чем " смысл " ошибки в названии?
Неправильная форма:
int &z = 12;
Правильная форма:
int y;
int &r = y;
Вопрос :
Почему первый код неправильный? В чем " смысл " ошибки в названии?
(ostringstream() << "x=" << x).str()
Ответы:
В C ++ 03 3.10 / 1 сказано: «Каждое выражение является либо lvalue, либо rvalue». Важно помнить, что ценность по сравнению с ценностью - это свойство выражений, а не объектов.
Lvalues именуют объекты, которые сохраняются за пределами одного выражения. Так , например, obj, *ptr, ptr[index]и ++xвсе lvalues.
Rvalue - это временные значения, которые испаряются в конце полного выражения, в котором они живут («точка с запятой»). Так , например, 1729, x + y, std::string("meow")и x++все rvalues.
Оператор адреса требует, чтобы его «операнд был lvalue». если бы мы могли взять адрес одного выражения, это выражение было бы lvalue, иначе это rvalue.
&obj; // valid
&12; //invalid
int & = 12;недействительно, стандарт говорит, что строковый литерал является lvalue, другие литералы - rvalue.
std::string("meow")конструирует объект типа std::stringи выдает rvalue, которое обозначает этот объект, 1729не имеет побочных эффектов и дает значение 1729 как значение типа int.
"Lvalues name objects that persist beyond a single expression."на 100% правильное утверждение. Напротив, ваш пример (const int &)1неверен, потому что это НЕ «именованный» объект.
int &z = 12;
С правой стороны временный объект типа intсоздается из интегрального литерала 12, но временный объект не может быть привязан к неконстантной ссылке. Отсюда и ошибка. Это то же самое, что:
int &z = int(12); //still same error
Почему создается временное? Поскольку ссылка должна ссылаться на объект в памяти, и для того, чтобы объект существовал, он должен быть сначала создан. Поскольку объект не имеет имени, это временный объект. У него нет названия. Из этого объяснения стало довольно ясно, почему второй случай хорош.
Временный объект может быть привязан к ссылке const, что означает, что вы можете сделать это:
const int &z = 12; //ok
Для полноты картины я хотел бы добавить, что в C ++ 11 введена ссылка на rvalue, которая может связываться с временным объектом. Итак, в C ++ 11 вы можете написать это:
int && z = 12; //C+11 only
Обратите внимание, что есть &&intead of &. Также обратите внимание, что constэто больше не нужно, даже если объект, с которым zсвязывается, является временным объектом, созданным из интегрального литерала 12.
Поскольку в C ++ 11 введена ссылка на rvalue , int&отныне она называется lvalue-reference .
12- это константа времени компиляции, которую нельзя изменить в отличие от данных, на которые ссылается int&. Что вы можете сделать, это
const int& z = 12;
void f( vector<int> const & ), которая идиоматична для передачи вектора, который не должен быть изменен. Теперь проблема в том, что это f( vector<int>(5) )было бы неправильно, и пользователю пришлось бы предоставить другую перегрузку, void f( vector<int> v ) { f(v); }которая является тривиальной.
f( vector<int>(5) )компилятор создает временный, а затем связывает ссылку с этим временным, и аналогично если было неявное преобразование из 5напрямую. Это позволяет компилятору генерировать единую подпись для функции и позволяет реализовать функцию одним пользователем. С этого момента аналогичное поведение определяется для остальных случаев использования постоянных ссылок для согласованности.
T const & r = *ptr;любое последующее использование rв функции может быть заменено на *ptr, и rне обязательно должно существовать во время выполнения) или его, возможно, придется реализовать, сохранив адрес объекта, которому он присваивает псевдоним (рассмотрите возможность сохранения ссылки как члена объекта) - что реализовано как указатель с автоматическим разыменованием.
Это правила языка C ++:
12), является "rvalue"int &ri = 12;сформированоВы должны понимать, что это правила C ++. Они просто есть.
Легко изобрести другой язык, скажем C ++ ', с немного другими правилами. В C ++ 'было бы разрешено создать неконстантную ссылку с rvalue. Здесь нет ничего непоследовательного или невозможного.
Но это позволило бы получить некоторый рискованный код, в котором программист мог бы не получить то, что он задумал, и разработчики C ++ справедливо решили избежать этого риска.
Ссылки - это «скрытые указатели» (ненулевые) на вещи, которые могут изменяться (lvalues). Вы не можете определить их как константу. Это должна быть «переменная» вещь.
РЕДАКТИРОВАТЬ::
Я думаю о
int &x = y;
как почти эквивалент
int* __px = &y;
#define x (*__px)
где __px- новое имя, и #define xработает только внутри блока, содержащего объявление xссылки.
const:)
const