Что произошло при назначении ссылки на rvalue lvalue? - PullRequest
0 голосов
/ 14 октября 2019

У меня есть простой пример:

void Message::move_Folders(Message *m) {
    m_folders = std::move(m->m_folders);
    for (auto f : m_folders) {
        f->removeMessage(m);
        f->addMessage(this);
    }
    m->m_folders.clear();
}

Эта функция может перемещать элемент «папки» из одной в другую. Итак, я хочу знать: нужно ли предоставить функцию назначения перемещения для «папок»?

folders &operator=(folders &&f) {
    ...
}

Что произошло при назначении ссылки на rvalue для lvalue? Это все еще операция копирования? (Полагаю, что нет.)

Примечание: папки - это набор объектов Folder. Сообщение может принадлежать многим папкам. Таким образом, сообщение содержит набор папок. Папка также имеет член messages. Папка может содержать много сообщений. Это немного сложно.

Это определение Message и Folder:

class Message {
public:
// constructor and destructor
...
private:
    std::set<Folder *> m_folders;
...
};

class Folder {
friend class Message;
//constructor and destructor
...
private:
    std::set<Message *> m_messages;
};

Спасибо

Ответы [ 3 ]

2 голосов
/ 14 октября 2019

Обратите внимание, что std::move ничего не двигает;скорее это делает вещь подвижной . Таким образом, чтобы действительно переместить m->folders в this->folders, действительно, назначение перемещения должно выполнять эту логику.

Фактически, это назначение перемещения должно отвечать за определение семантики перемещения: move_folders метод не должен очищать m->folders, так как он не должен знать эту деталь.

1 голос
/ 14 октября 2019

Необходимость предоставления заданного пользователем назначения перемещения зависит от того, какие другие специальные члены вы уже определили, см. Изображение для комбинаций: enter image description here

Так что, если в папках нетпользовательский деструктор, конструктор копирования или оператор присваивания, затем конструктор перемещения и присваивание будут неявно объявлены компилятором. В противном случае вам нужно будет написать его самостоятельно.

Что произошло при назначении значения rvalue для lvalue? Это все еще операция копирования? (Полагаю, что нет.)

Зависит от того, есть ли у вас задание на перемещение, которое оно будет перемещать, иначе оно будет копироваться.

Наконец, вам нужно задание на перемещение для вашего класса папки для перемещенияНа самом деле std :: set - Нет, поскольку назначение перемещения в std :: set не перемещает содержимое одно за другим с помощью распределителя по умолчанию.

0 голосов
/ 14 октября 2019

Вам не нужно для предоставления оператора назначения перемещения, но если вы этого не сделаете, вызов действительно будет понижен до копии.

...