为什么post-increment需要复制而pre-increment不需要

Why post-increment needs to make a copy while pre-increment does not

我知道这个问题已经讨论过好几次了,但是我找不到 post 来解释为什么在 post-increment 操作的情况下需要制作副本。

引用来自 Whosebug 的回复:

int j = i++; // j will contain i, i will be incremented.
int j = ++i; // i will be incremented, and j will contain i+1.

当考虑 post/pre 增量的定义时,这完全有意义。很多时候比较pre/post增量的性能时说post增量需要做一个副本,增量它和return副本而预增量只是增加价值而不创造复印件。

虽然性能对比了几十post秒,但我实在找不到任何解释为什么在post增量的情况下必须进行复制。为什么它不 return 旧值然后将变量的值递增一个(或者运算符重载的方式),而不是创建一个新对象然后 return 那个。

不同之处在于 someval++ returns 增量之前的 someval 是什么,要做到这一点,您需要记住副本中的 someval 是什么。如果原始值未存储在某处,您还可以如何在更新原始值时 return 原始值?

将预递增和post-递增运算符视为标准函数:

// ++i
int pre_increment(int &i) {
    i = i + 1;
    return i;
}

// i++
int post_increment(int &i) {
    int original_i = i;
    i = i + 1;
    return original_i;
}

这应该可以帮助您理解为什么在第二种情况 (i++) 中,您必须在执行递增之前执行值的复制。

我很难说编译器如何优化预递增和 post-递增运算符,以便不必在基本类型上进行复制。

我可以展示如何为 post-增量运算符的用户定义类型制作副本。

让我们简单地看一下std::vector::iterator

假设迭代器除了存储其他内容外,还存储一个索引。

struct iterator
{
   size_t index;

   iterator operator++(int )
   {
      iterator copy = *this;
      this->index++;
      return copy;
   }
 };

在这种情况下,不可能先return *this 然后递增索引。创建副本,增加 this 的索引,然后 returning 副本允许我们保留该操作的语义。