Код, который кажется неправильным при компиляции (о возврате объекта)

Недавно кто-то задал мне вопрос о построении возвращаемого значения функции. После нескольких дискуссий я обнаружил, что что-то не так. Вот образец:

#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 рассматривается как значение.

Другие вопросы по тегам