В cppreference сказано, что
Конструкторы копирования/перемещения не должны присутствовать или быть доступными в операторе return, когда операнд является значением prvalue того же типа класса (игнорируя cv-квалификацию), что и возвращаемый тип функции:
T f() { return T(); } f(); // only one call to default constructor of T
Правильно ли я понимаю, и для того, чтобы приведенный выше пример работал, неизбежно иметь хотя бы один конструктор копирования или перемещения?
Я пробовал следующее:
class Player
{
//...
public:
Player();
Player(std::string name);
Player& operator=(const Player&) = delete;
Player& operator=(Player&& p) = delete;
Player(const Player& origin) = delete;
Player(Player&& p) = delete;
Player getEmptyPlayer() const {
return Player("Name");
}
}
//in main:
Player p1("It's Me");
Player p2 = p1.getEmptyPlayer();
Почему этот код компилируется и работает? Насколько я понимаю, на самом деле метод getEmptyPlayer() должен вызывать конструктор копирования для копирования объекта при возврате. Из-за повышения эффективности компилятором это не так, но исключение копирования (NRVO) приходит на смену и напрямую создает объект там, где он должен быть, а не делает копию. Тем не менее, cppreference (см. выше) говорит, что должен существовать доступный или присутствующий конструктор копирования/перемещения. Так что же здесь происходит?
Заранее спасибо!