Biorąc pod uwagę tę aplikację:Czy legalne jest, aby podczas inicjalizacji usunąć nietrywialny konstruktor copy/move?
#include <iostream>
struct X {
X(int _x) { x = _x + 1; }
X(const X& that) { x = that.x + 10; }
X& operator=(const X& that) { x = that.x + 100; return *this; }
X(X&& that) { x = that.x + 1000; }
X& operator=(X&& that) { x = that.x + 10000; return *this; }
int x;
};
int main() {
X a(1);
std::cout << "a.x=" << a.x << std::endl;
X b = 2;
std::cout << "b.x=" << b.x << std::endl;
X c = X(3);
std::cout << "c.x=" << c.x << std::endl;
X d = a;
std::cout << "d.x=" << d.x << std::endl;
}
ja oczekiwane wyjście będzie:
a.x=2
b.x=1003
c.x=1004
d.x=12
Jeszcze co pojawia się:
a.x=2
b.x=3
c.x=4
d.x=12
Jedynym sposobem, aby dostać moje oczekiwane wyniki to kompilacja z -fno-elide-constructors
(example)
Pomyślałem, że kompilator nie może przesuwać rzeczy, jeśli to wpłynie na obserwowane zachowanie, ale GCC, klang i MSVC wydają się właśnie to robić.
Czy brakuje jakiejś ogólnej zasady lub czy jest to specyficzne dla inicjalizacji obiektu z tymczasowym?
dupe/powiązane z [this] (http://stackoverflow.com/questions/24559875/can-functions-be-optimized-away-if-they-have-side-effects) i/lub [to] (http://stackoverflow.com/questions/9253316/under-what-conditions-does-c-optimize-out-constructor-calls) – NathanOliver
Ponadto, 'X b = 2;' inicjuje i nigdy nie używa operatora przypisania . –