STL的迭代器,前置++什么比后置++要快?

内置类型的前置++和后置++

int a = 0;
int b = a++; //此时b=0,a=1

int c = 0;
int d = ++c; // 此时d = 1, c = 1

换言之,前置++和后置++的区别仅在于++运算符的返回值是自加过后的结果或者是自加之前的副本

在类中重载它们

class Age   
	{   
	public:   
	  
	    Age& operator++() //前置++   
	    {   
	        ++i;   
	        return *this;   
	    }   
	  
	    const Age operator++(int) //后置++   
            {   
	        Age tmp = *this;   
	        ++(*this);  //利用前置++   
	        return tmp;   
	    }   
	  
	    Age& operator=(int i) //赋值操作   
	    {   
	        this->i = i;   
	        return *this;   
	    }   
	  
	private:   
	    int i;   
	};

可以看出,如果只是单纯的为了把私有变量i加一,后置++要使用一个tmp在函数栈上保存自加之前的类的副本,会造成额外的内存开销,没有必要,除非遇到了要保存自加前副本的需求。

在STL中的迭代器自加

vector<int> vi{1,2,3};
for (auto iter = vi.begin(); iter != vi.end(); iter++);
for (auto iter = vi.begin(); iter != vi.end(); ++iter);

这样的迭代中,使用++运算符,只是为了让迭代器内置的指针加一而已,并不需要指针移动之前迭代器的副本,所以使用前置++会比后置++更加节省内存,BTW,经测试,在VS2019的环境下,后置++编译器还真没办法优化

关于重载运算符的返回值(2020/02/29更新)

今天有小伙伴提到,将后置或者前置的重载操作符的函数的返回值设为void也能顺利通过编译并且实现部分功能。但是经过试验,如果前置或者后置的重载操作符的返回值是void,那么编译以下代码就会报错:

class MyInt
{
public:
    MyInt() : i(0){}

    MyInt& operator++()
    {
        i = i + 1;
        return *this;
    }

    void operator++(int i)
    {
        i = i + 1;
    }

private:
    int i;
};

int main()
{
    MyInt i1, i2;
    i1 = ++i2;    // OK
    i2++;         // OK
    i1 = i2++;    // Compile Error!
    return 0;
}
posted @ 2019-08-09 10:15  joeyzzz  阅读(1198)  评论(1编辑  收藏  举报