Здравствуйте, Ароан, Вы писали:
А>Но возникает другой вопрос, зачем все это надо? А>Есть ли какая-то разумная причина возвращать l-value?
Конечно. Использование префиксного инкремента позволяет избежать создания временного объекта.
// Тут компилятор может оптимизировать код, заменив постфиксный инкремент на префиксный.for (int i=0; i<10; i++) {}
class A
{/*...*/};
// А вот тут компилятор не имеет права выполнить оптимизацию, т.к. a++ может иметь побочный эффект.
// Кроме того, префиксная форма ++ для пользовательского типа может не отвечать принятой семантике.
// Поэтому убедиться в законности такой замены не под силу большинству компиляторов (если не всем).for (A a=/*...*/; /*...*/; a++) {}
Re[4]: Почему в С++ можно ставить плюсы перед ++С...
Здравствуйте, Ароан, Вы писали:
А>Объясните почему на C++ работает следующая конструкция:
Оба постфиксный и префиксный ++ должны применяться к lvalue (для встроенных типов). НО: Префиксный оператор инкремента возвращает lvalue, а постфиксный — rvalue.
А>
А>(++С)++ // преинкремент возвращает lvalue, поэтому к нему можно применять постинкремент
А>
А>А вот такая не работает:
А>
А>++(С++) // постинкремент возвращает rvalue, поэтому преинкремент обламывается
А>
А>Можно подумать что постфиксный ++ не требует l-value, но такие конструкции тоже не работают:
А>
А>++(С+1) // в обоих случаях попытка применить
А>(С+1)++ // оператор (пре/пост)инкремента к rvalue
А>
Здравствуйте, Ароан, Вы писали:
А>Объясните почему на C++ работает следующая конструкция:
А>
А>(++С)++
А>
А>А вот такая не работает:
А>
А>++(С++)
А>
in fact, internal implementation of postfix operator ++ returns r-value,
preffix operator ++ requires l-value and none r-values can be converted to l-values,
but l-values can be converted to r-values.
in the statement like ++a++ => ++(a++) we have following operator precedence:
first will be availuated postfix ++, then its returned r-value will be passed to preffix ++
as it was said, none r-value can be converted to l-value,
in case of ++(a++) you just did the statement more clear for guys how does not know operator precedence rules
but not changed the way statement ++a++ is avaluated.
UDTs can have their own postfix and preffix operators, so that it would be possible
to write ++a++ if a is an instance of UDT type.
That's it!
PS:
For your information:
An object is a contiguous region of storage. An lvalue is an expression that refers to such an object. The original
definition of lvalue referred to an object that can appear on the left-hand side of an assignment. However, const
objects are lvalues that cannot be used in the left-hand side of an assignment. Similarly, an expression that can appear
in the right-hand side of an expression (but not in the left-hand side of an expression) is an rvalue.
An lvalue can appear in a context that requires an rvalue; in this case, the lvalue is implicitly converted to an rvalue.
An rvalue cannot be converted to an lvalue. Therefore, it is possible to use every lvalue expression in the example as
an rvalue, but not vice versa.
PPS
Sorry for using English, don't have a localized keyboard on this machine.
Re[2]: Почему в С++ можно ставить плюсы перед ++С...
Зачем возвращать l-value я понял. Но тогда возникает еще один вопрос.
Есть ли какая-то разумная причина возвращать r-value?
В своем классе у меня этого не получилось сделать. Если без ссылки — временный объект создается и получаем l-value. Если возвращать по ссылке — временный объект не создается и все равно получаем l-value.
Можно написать как угодно ++С++, (++С)++, ++(С++).