Раньше было предпочтительным предварительное приращение, потому что перегруженный пост-инкремент в классе требовал возврата временной копии, которая представляла состояние объекта до приращения.
Похоже, что это уже не вызывает серьезной озабоченности (до тех пор, пока накладывается inlining), поскольку мой старый компилятор С++ (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
Однако, если ничего не встроено, кажется, все еще есть преимущество в предпочтении предварительного приращения для пост-приращения, поскольку
test_post
вынужден вызывать вoperator++(int)
.
Предположим, что operator++(int)
встроен как конструктор идиоматической копии, вызывает предварительный приращение и возврат копии, как показано выше. Если конструктор копирования является inlined или реализацией конструктора по умолчанию, является ли достаточная информация для компилятора для оптимизации пост-инкремента, чтобы test_pre
и test_post
стали идентичными функциями? Если нет, то какая другая информация требуется?