I wrote this short test code
# include <iostream>
using std::cout;
struct P
{
P()
{cout << "I'm P::P()\n";};
P(const P& p)
{cout << "I'm P::P(const P&)\n";}
P(P&& p)
{cout << "I'm P::P(P&&)\n";}
};
int main()
{
P pa, pe(pa);
P pi((P(pa))), // this should be an object declaration
pu(std::move(pa)); // as well as this one
P po(P(pa)); // this is, instead, a function declaration
}
and I got the following output
I'm P::P()
I'm P::P(const P&)
I'm P::P(const P&)
I'm P::P(P&&)
I have understood all but the third line of output, coming from the instantiation of the pi
object: why is the copy constructor being called and not the move constructor as it happens for the pu
object?
Shouldn't the P(pa)
parameter be an unnamed non-const rvalue? How can it be bound to a lvalue reference? Or the third line comes from the copy
constructor instantiating the parameter itself? In this case who constructs pi
? Is there some kind of optimization ?