Recently someone asked me a question about the constructing of a return value of a function. After a few of discussions I found that something seems not right. Here is the sample:
#include <conio.h>
#include <stdio.h>
#include <iostream>
/*
struct A // Won't be compiled
{
A(void) {};
A(const A &) {};
A(A &&) = delete;
};
*/
struct A // Compiled but...
{
A(void) {};
A(const A &) = delete;
A(A &&) {};
};
A func(void)
{
A temp;
return temp;// 'temp' is a named object, so it should be a lvalue and the A(const A &) should have been invoked.
//return std::move(temp); // OK.
}
int main(void)
{
func();
_getch();
return(0);
}
It will be compiled (either by VC or by gcc)... But it looks wrong.
The question is: Even any copy-deducing condition has been triggered, There seems no reason to let the 'A(const A &)' be ignored, isn't it?
12.8 [class.copy]:
32 - When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. [...]
NRVO permits copy elision, so temp
is treated as an rvalue.