我之前已经问过类似的问题,但是对于某些细节仍不清楚。
在什么情况下会调用postblit构造函数?
移动一个对象的语义是什么?它会被postblitted和/或析构吗?
如果我通过值返回一个局部变量,会发生什么?它会被隐式移动吗?
如何将表达式强制转换为rvalue?例如,泛型swap会是什么样子?
我之前已经问过类似的问题,但是对于某些细节仍不清楚。
在什么情况下会调用postblit构造函数?
移动一个对象的语义是什么?它会被postblitted和/或析构吗?
如果我通过值返回一个局部变量,会发生什么?它会被隐式移动吗?
如何将表达式强制转换为rvalue?例如,泛型swap会是什么样子?
一个postblit构造函数在结构体被复制时调用 - 例如将结构体传递给一个函数。
移动是一种按位复制。postblit构造函数永远不会被调用。析构函数也永远不会被调用。比特位只是被复制了。原始数据被“移动”了,因此不需要创建或销毁任何内容。
它将被移动。这是移动的典型示例。
如果要使swap函数尽可能高效,它必须考虑到许多不同的情况。我建议直接使用std.algorithm中的swap函数。经典交换会导致复制,因此会调用postblit构造函数和析构函数。移动通常由编译器完成,而不是程序员。但是,查看官方实现的swap函数,看起来它会进行一些技巧以从中获得移动语义。无论如何,移动通常由编译器执行。它们是一种优化,只有在它知道可以这样做时才会执行(RVO是它可以执行的典型情况)。
因此,编译器可能会在其他地方使用移动操作,但不能保证会这样做。
- 所有匿名 rvalue 都会被移动,而不是复制。当源是匿名 rvalue 时(即在函数
hun
中出现的临时变量),不会插入对this(this)
的调用。- 在函数内部分配到堆栈中并返回的所有命名临时对象都会省略调用
this(this)
。- 不能保证观察到其他潜在的省略。
swap
,稍后再链接到实际实现,因此如果有人在使用github链接时遇到任何问题,现在将是“查看官方实现”的链接。但我没有遇到过链接问题。也许这是浏览器问题。 - Jonathan M Davis就我所了解的情况:
1)当一个结构体被复制时,与移动或构造不同。
2)移动语义的重点是两者都不需要发生。结构体的新位置使用结构体的按位复制进行初始化,旧位置超出范围并且无法访问。因此,结构体已从A移动到B。
3)这是典型的移动情况:
S init(bool someFlag)
{
S s;
s.foo = someFlag? bar : baz;
return s; // `s` can now be safely moved from here...
}
// call-site:
S s = init(flag);
//^ ... to here.
void swap(T)(ref T t1, ref T t2) {T tmp = t1; t1 = t2; t2 = tmp;}
- ratchet freak[string](url)
。详情请参见此处。 - Alexander Malakhov