перемещение временного значения с использованием ссылки rvalue

0

Я пытаюсь опустить семантику перемещения, и я написал этот пример. Я хотел бы переместить временное значение 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&)'
  • 5
    Конструкторы копирования (и перемещения) MemoryPage неявно определены как удаленные / не объявленные, поскольку вы предоставляете пользовательский оператор присваивания перемещения. Возврат объекта, как в случае return mp; требуется либо копия, либо конструктор перемещения (даже если он не вызывается). Обязательно следуйте правилу пяти.
  • 3
    Видите, Правило Три становится Правилом Пяти с C ++ 11?
Показать ещё 1 комментарий
Теги:
c++11
move-semantics

1 ответ

0
Лучший ответ

Конструктор копирования:

[...] определяется как удаленный, если выполнено одно из следующих условий:

  • 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() { }
};
  • 0
    Вы даже можете по умолчанию виртуальный дтор.
  • 0
    Я думаю, что важной частью ответа является то, где в коде ОП требуется код копирования / перемещения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню