Я узнал о (N) RVO в течение последних нескольких дней. Как я читал о cppreference в статье об исключении копии для С++ 14:
... компиляторам разрешено, но не требуется пропускать конструкцию копирования и перемещения (начиная с С++ 11) объектов класса, даже если конструктор копирования/перемещения (начиная с С++ 11) и деструктор имеют наблюдаемую сторону -эффекты. Это оптимизация: даже если она имеет место и не вызывается конструктор копирования/перемещения, он все равно должен присутствовать и быть доступным (как если бы оптимизация не выполнялась в момент all), в противном случае программа некорректна.
Таким образом, конструктор копирования или перемещения должен присутствовать и быть доступным. Но в приведенном ниже коде:
#include <iostream>
class myClass
{
public:
myClass() { std::cout << "Constructor" << std::endl; }
~myClass() { std::cout << "Destructor" << std::endl; }
myClass(myClass const&) { std::cout << "COPY constructor" << std::endl;}
myClass(myClass &&) = delete;
};
myClass foo()
{
return myClass{};
}
int main()
{
myClass m = foo();
return 0;
}
Я получил следующую ошибку: test.cpp: In function 'myClass foo()':
test.cpp:15:17: error: use of deleted function 'myClass::myClass(myClass&&)'
return myClass{};
. Я получаю эту ошибку, даже если я не вызываю foo()
из main()
. Та же проблема с НРВО.
Следовательно, всегда требуется конструктор перемещения, не так ли? (пока копии нет, я проверял)
Я не понимаю, где компилятору нужен конструктор перемещения. Мое единственное предположение состоит в том, что это может потребоваться для создания временной переменной, но это звучит сомнительно. Кто-нибудь знает ответ?
О компиляторе: пробовал на компиляторах g++ и VS, проверить можно онлайн: http://rextester.com/HFT30137< /а>.
P.S. Я знаю, что в стандарте С++ 17 RVO обязателен. Но NRVO — нет, поэтому я хочу изучить, что здесь происходит, чтобы понять, когда я могу использовать NRVO.