将右值引用分配给左值时发生了什么?

What happened when assigning an rvalue reference to lvalue?

我有一个简单的例子:

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" 成员从一个移动到另一个。所以我想知道:我需要为 "folders" 提供移动分配功能吗?

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

将右值引用分配给左值时发生了什么?还是复制操作? (我相信不是。)

注意:文件夹是一组文件夹对象。一条消息可能属于多个文件夹。所以一条消息包含一组文件夹。该文件夹还有一个成员 messages。一个文件夹可能包含许多消息。有点复杂。

这是MessageFolder的定义:

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;
};

谢谢

不需要提供移动赋值运算符,但如果不这样做,调用确实会降级为副本。

请注意,std::move 不会移动任何东西;相反,它使事物 可移动 。因此,为了真正将 m->folders 移动到 this->folders,移动赋值确实必须执行该逻辑。

事实上,那个移动赋值应该是负责定义移动语义的那个:move_folders 方法不必清除 m->folders 因为它不应该知道这个细节。

是否需要提供用户定义的移动分配取决于您已经定义的其他特殊成员,请参见图片了解组合:

因此,如果 Folders 没有用户定义的析构函数、复制构造函数或赋值运算符,则编译器将隐式声明移动构造函数和赋值运算符。否则你需要自己写一个。

What happened when assigning an rvalue to lvalue? Is it still a copy operation? (I believe not.)

这取决于你是否有移动任务,它会移动,否则它会复制。

最后你需要为你的文件夹class移动赋值移动std::set实际上是否,因为std::set的移动赋值不会用默认分配器。