In this code:
#include <iostream>
using std::cout;
class Foo {
public:
Foo(): egg(0) {}
Foo(const Foo& other): egg(1) {}
int egg;
};
Foo bar() {
Foo baz;
baz.egg = 3;
return baz;
}
int main(void) {
Foo spam(bar());
cout << spam.egg;
return 0;
}
the output is 3
, while I expected it to be 1
.
That means the copy constructor is not called in the line Foo spam(bar())
.
I guess it's because the bar
function doesn't return a reference.
Could you please explain what's really going on at the initialization of spam
?
I apologize in advance if that's a dumb question.
Thanks!
Best Answer
Copy/move elision is the only allowed exception to the so-called "as-if" rule, which normally constrains the kinds of transformations (e.g. optimizations) that a compiler is allowed to perform on a program.
The rule is intended to allow compilers to perform any optimization they wish as long as the transformed program would work "as if" it was the original one. However, there is one important exception.
Per paragraph 12.8/31 of the C++11 Standard:
In other words, you should never rely on a copy constructor or move constructor being called or not being called in the cases for which the provisions of 12.8/31 apply.