Я пытаюсь опустить семантику перемещения, и я написал этот пример. Я хотел бы переместить временное значение r в объект в стеке.
class MemoryPage
{
public:
size_t size;
MemoryPage():size(0){
}
MemoryPage& operator= (MemoryPage&& mp_){
std::cout << "2" <<std::endl;
size = mp_.size;
return *this;
}
};
MemoryPage getMemPage()
{
MemoryPage mp;
mp.size = 4;
return mp;
}
int main() {
MemoryPage mp;
mp = getMemPage();
std::cout << mp.size;
return 0;
}
Я получаю эту ошибку при возврате getMemPage():
error: use of deleted function 'constexpr MemoryPage::MemoryPage(const MemoryPage&)'
Конструктор копирования:
[...] определяется как удаленный, если выполнено одно из следующих условий:
- T имеет пользовательский конструктор перемещения или оператор назначения перемещения
Чтобы решить ближайшую проблему, вы просто предоставляете конструктор копирования, то есть:
MemoryPage(const MemoryPage&) { }
Однако, как отмечается в комментариях, неплохо проконсультироваться с Правилом-тройкой становится "Правило пяти" с С++ 11? , В частности, в этом параграфе кратко излагаются, с какими проблемами вы столкнетесь, если не будете выполнять какие-либо специальные функции-члены:
Обратите внимание, что:
move constructor и move assign operator не будет сгенерирован для класса, который явно объявляет любую из других специальных функций-членов
конструктор копирования и оператор присваивания копии не будут сгенерированы для класса, который явно объявляет конструктор перемещения или переводит оператор присваивания
класс с явно объявленным деструктором и неявно определенным конструктором копирования или неявно определенным оператором присваивания копии считается устаревшим.
форматированный для удобочитаемости
Поэтому это хорошая практика при написании класса, который занимается управлением памятью, чтобы предоставить все пять специальных функций-членов, то есть:
class C {
C(const C&) = default;
C(C&&) = default;
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
virtual ~C() { }
};
MemoryPage
неявно определены как удаленные / не объявленные, поскольку вы предоставляете пользовательский оператор присваивания перемещения. Возврат объекта, как в случаеreturn mp;
требуется либо копия, либо конструктор перемещения (даже если он не вызывается). Обязательно следуйте правилу пяти.