Consider the following:
#include <iostream>
#define trace(name) std::cout << #name << " (" << this << "), i = " << i << std::endl
class C
{
C(C const&);
C& operator=(C const&);
public:
int i;
C() : i(42) { trace(CTOR); }
C(C&& other) : i(other.i) { trace(MOVE); other.i = 0; }
C& operator=(C&& other) { trace(ASGN); other.i = 0; return *this; }
~C() { trace(DTOR); }
};
C
func1(bool c)
{
C local;
if (c)
return local;
else
return C();
}
int
main()
{
C local(func1(true));
return 0;
}
Both MSC and g++ allow the return local
, and use the move constructor (as shown by the output) when doing so. While this makes a lot of sense to me, and I think it probably should be the case, I can't find the text in the standard that authorizes it. As far as I can see, the argument to the move constructor must be either a prvalue (which it clearly isn't) or an xvalue; it is in fact an lvalue, which would make the return just as illegal as C other = local;
in the function body (which does fail to compile).