Возможный дубликат:
Почему конструктор копирования не вызывается в этом случае?
Что такое оптимизация копирования и возвращаемое значение?
Может кто-нибудь объяснить мне, почему следующая программа выдает «cpy: 0» (по крайней мере, при компиляции с g ++ 4.5.2):
#include<iostream>
struct A {
bool cpy;
A() : cpy (false) {
}
A (const A & a) : cpy (true) {
}
A (A && a) : cpy (true) {
};
};
A returnA () { return A (); }
int main() {
A a ( returnA () );
std::cerr << "cpy: " << a.cpy << "\n";
}
Вопрос возник, когда я попытался выяснить, казалось бы, странный результат этого примера: переместить ctor класса с постоянным элементом данных или ссылочным элементом
Компилятор может свободно копировать и перемещать конструкцию, даже если они имеют побочные эффекты, для объектов, которые он создает от своего имени. Временные объекты и возвращаемые значения часто создаются непосредственно в правильном месте, исключая их копирование или перемещение. Для возвращаемых значений вы должны быть немного осторожны, чтобы иметь право выбора.
Если вы хотите предотвратить исключение при копировании, вам, по сути, нужно вернуть два объекта-кандидата:
bool flag(false);
A f() {
A a;
return flag? A(): a;
}
Если вы не изменились flag
это всегда будет создавать копию a
(если компиляторы не стали умнее со времени последней попытки).
Других решений пока нет …