简体   繁体   English

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

[英]What happened when assigning an rvalue reference to lvalue?

I have a simple example:我有一个简单的例子:

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

This function can move the "folders" member from one to another.这个 function 可以将“文件夹”成员从一个移动到另一个。 So I want to know: Need I provide a move assign function for "folders"?所以我想知道:我需要为“文件夹”提供移动分配 function 吗?

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

What happened when assigning an rvalue reference to lvalue?将右值引用分配给左值时发生了什么? Is it still a copy operation?还是复制操作吗? (I believe not.) (我相信不会。)

Note: folders is a set of the Folder objects.注意:文件夹是一组文件夹对象。 A message may belong to many folders.一条消息可能属于许多文件夹。 So a message contains a set of Folders.所以一条消息包含一组文件夹。 The Folder also has a member messages .该文件夹也有一个成员messages A folder may contain many messages.一个文件夹可能包含许多消息。 It's a little complicated.这有点复杂。

This is the definition of Message and Folder :这是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;
};

Thanks谢谢

Note that std::move does not move a thing;注意std::move不会移动任何东西; rather it makes the thing movable .相反,它使事物可移动 So in order to actually move the m->folders into this->folders , indeed the move assignment must perform that logic.因此,为了实际将m->folders移动到this->folders中,移动分配确实必须执行该逻辑。

In fact, that move assignment should be the one responsible to define the move semantics: the move_folders method does not have to clear m->folders since it should not know this detail.事实上,移动分配应该负责定义移动语义: move_folders方法不必清除m->folders ,因为它不应该知道这个细节。

The need to provide a user defined move assignment depends on what other special members you have already defined, see the image for combinations:是否需要提供用户定义的移动分配取决于您已经定义了哪些其他特殊成员,请参见图像了解组合: 在此处输入图像描述

So if Folders does not have a user defined destructor, copy constructor or assignment operator, then move constructor and assignment will be implicitly declared by the compiler.因此,如果 Folders 没有用户定义的析构函数、复制构造函数或赋值运算符,则移动构造函数和赋值将由编译器隐式声明。 Otherwise you will need to write one yourself.否则你需要自己写一个。

What happened when assigning an rvalue to lvalue?将右值分配给左值时发生了什么? Is it still a copy operation?还是复制操作吗? (I believe not.) (我相信不会。)

It depends if you have a move assignment it will move, else it will copy.这取决于您是否有移动分配,它会移动,否则它将复制。

Finally do you need move assignment for your Folder class to move std::set is actually No, since the move assignment of std::set does not move the contents one by one with the default allocator.最后,您是否需要为您的文件夹 class 移动分配来移动 std::set 实际上是否,因为 std::set 的移动分配不会使用默认分配器一一移动内容。

You do not need to provide a move-assignment operator, but if you don't the call will indeed be downgraded to a copy.不需要提供移动分配运算符,但如果您不这样做,调用确实会降级为副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM