Код, который кажется неправильным при компиляции (о возврате объекта)
Недавно кто-то задал мне вопрос о построении возвращаемого значения функции. После нескольких дискуссий я обнаружил, что что-то не так. Вот образец:
#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);
}
Он будет скомпилирован (либо VC, либо gcc)... Но выглядит неправильно.
Вопрос в том, что даже любое условие, вызывающее копирование, было вызвано. Кажется, нет причин игнорировать "A(const A &)", не так ли?
1 ответ
12,8 [class.copy]:
32 - Когда критерии для исключения операции копирования выполнены или будут выполнены, за исключением того факта, что исходный объект является параметром функции, а копируемый объект обозначается lvalue, разрешение перегрузки для выбора конструктора для Копирование сначала выполняется, как если бы объект был обозначен как rvalue. [...]
NRVO разрешает копирование, поэтому temp
рассматривается как значение.