В C++ я понимаю это (++i)
должен возвратить ссылку на i
потому что потребность конкатенации операторов, но что я не могу выяснить:
Почему (i++)
должен возвратиться i
значением?
Может любой разъясняться.
++ i
можно записать как
prefix_inc (this) {
increase this by 1
return this
}
Поскольку возвращается реальный i
, мы можем взять на него ссылку. Однако i ++
выглядит как
postfix_inc (this) {
set old_this = copy of this
increase this by 1
return old_this
}
, поскольку old_this
- это просто локальная переменная, ссылка на нее бессмысленна после завершения i ++
. По логике вещей он должен возвращать rvalue.
int i = 0;
Console.Writeline(i++); // Output 0, after that, i will be 1
int x = 0;
Console.Writeline(++x); // Output 1
Примечание: код находится на C #
5 центов:
Вследствие того, что i++
делает копию, это медленнее для переменных, не являющихся POD (т.е. итераторов). Вы должны использовать ++i
везде, где это возможно.
Лично я всегда использую for(...;...;++i)
вместо for(...;...;i++)
, хотя компилятор должен это оптимизировать.
i ++
возвращает значение, поскольку возвращает старое значение i
, а i
увеличивается на 1
.
Базовая реализация этого будет:
int i++() {
int old = i;
i = i + 1;
return old;
}
Итак, если он вернет ссылку, это будет неправильное значение ... поскольку значение i
было увеличивается!
Пусть foo
- некоторая функция. foo(i++)
вызывает foo(i)
со старым значением i
и увеличивает i
, отсюда необходимость создания временной копии. foo(++i)
увеличивает i
и затем вызывает foo
с увеличенным значением, поэтому для лучшей производительности мы можем повторно использовать одну и ту же переменную, нет необходимости во временной копии.
i++ Это возвращает значение i до того, как оно будет увеличено. Идея заключается в том, что если вы хотите использовать i в функции, а затем увеличить значение после его использования, вы можете сделать это за один шаг. В качестве примера вот как я перегрузил бы этот оператор для целых чисел.
Integer Integer::operator++()
{
Integer returnValue = *this;
this->increment();
return returnValue;
}
Таким образом, он увеличивает значение, а затем возвращает то, что было раньше. Он также не возвращает ссылку, потому что возврат ссылки будет отличаться от того, что было передано изначально, что нарушит каскадирование.
++i Это увеличивает значение i, а затем возвращает новое значение. Это можно использовать в ситуации, когда вы хотите увеличить i, а затем использовать новое значение в вашей функции.
Integer Integer::operator++(Integer i)
{
i.increment();
return i;
}
Таким образом, возвращаемое значение - это увеличенное значение i.
.Хотя префикс ++i
возвращает увеличенное значение, а суффикс i++
возвращает старое значение и увеличивает его после этого, выбор оператора имеет значение, если вы заботитесь о процессорных циклах. Префиксный инкремент быстрее ;-)
Если вы когда-либо попадаете в ситуацию, когда это имеет значение, вы делаете это неправильно.