过去首选预增量,因为类上的重载后增量需要返回表示增量前对象状态的临时拷贝。
这似乎不再是一个严重的问题(只要内联到位),因为我的旧 C++ 编译器 (GCC 4.4.7) 似乎将以下两个函数优化为相同的代码:
class Int {
//...
public:
Int (int x = 0);
Int & operator ++ ();
Int operator ++ (int) {
Int x(*this);
++*this;
return x;
}
};
Int & test_pre (Int &a) {
++a;
return a;
}
Int & test_post (Int &a) {
a++;
return a;
}
这两个函数的最终程序集是:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
call _ZN3IntppEv
movq %rbx, %rax
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc
If nothing is inlined, however, there seems to still be a benefit to preferring pre-increment to post-increment, since
test_post
is forced to call out intooperator++(int)
.
让我们假设 operator++(int)
被内联为一个惯用的复制构造函数,调用预增量,并返回拷贝,如上所示。如果复制构造函数是内联的或默认的复制构造函数实现,那么编译器是否有足够的信息来优化后增量,以便test_pre
和test_post
变成相同的功能?如果没有,还需要什么其他信息?
最佳答案
是的。对于内置类型应该无关紧要。对于此类类型,编译器可以轻松分析语义并优化它们——如果这不会改变行为。
但是,对于类类型,它可能(如果不是确实)很重要,因为在这种情况下语义可能更复杂。
class X { /* code */ };
X x;
++x;
x++;
最后的两个调用可能完全不同并且可能执行不同的事情,就像这些调用一样:
x.decrement(); //may be same as ++x (cheating is legal in C++ world!)
x.increment(); //may be same as x++
所以不要让自己陷入语法糖的陷阱。
关于c++ - 是不是更喜欢预增量而不是后增量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036749/