What you're seeing here is the effect of copy elision. Copy elision is an optimization specified by the standard that enables the compiler, in a situation where you return an object from the stack, to have the function build the object in the caller's stack space and bypass the copy and move constructors altogether, regardless of side effects. Side effects, in your case, are what the constructor would print to cout
.
We can prevent the compiler from using this shortcut by using, for instance, a unique_ptr
to create the object on the heap. It's a little more involved, but it gets you the result you expect:
#include <unique_ptr>
Foo test()
{
unique_ptr<Foo> f(new Foo);
return move(*f);
}
In this case you need to move the pointee of f
because unique_ptr
's operator*
returns a reference, not a temporary. If you don't move it, it'll call the copy constructor instead.