C++11 §27.5.4.2/21:
void swap(basic_ios& rhs);
效果:*this
和rhs
的状态应该互换,只是rdbuf()
返回的值与函数调用前的值相同,rhs.rdbuf()
返回的值与函数调用前的值相同。
这种部分交换有什么用呢?
它会带来麻烦吗?
发布于 2011-11-17 01:56:48
你可以为此责怪我。委员会曾试图改变(我想是两次),但每次的解决方案都以破坏事情告终。
交换和移动语义在我们的I/O系统设计十年后进行了改造。这不是一个完美的契合。
请注意,basic_ios::swap
是一个受保护的成员函数,没有名称空间范围的变体。因此,这只能从派生类(通常是istream/ostream)调用。请注意,i/o_stream::swap
也是受保护的,没有名称空间范围的变体。它们的规范是调用基类swap
,然后交换任何本地数据(比如istream
中的gcount
)。
最后,在string/filestream
级别上,您会得到您认为是“普通”swap
的东西:公共成员和名称空间范围的变体。在这个级别上,您有一个数据成员string/file buffer
( rdbuf
)和一个基类。这一级的swap
简单地交换了基本成员和数据成员。
所有这一切的复杂特征是,基类中的rdbuf()
实际上是指向派生类的streambuf
(basic_filebuf
或basic_stringbuf
)的自引用指针,就是您不希望基类交换这些自引用指针的原因。
这使得基本swap
很奇怪,但除了派生客户端之外,每个人都受到保护。随后,派生客户端的swap
的代码看起来很简单。在派生级别,swap
是公开的,并以公共客户端期望的方式运行。
类似的舞蹈也适用于移动构造和移动分配。由于基类是一个虚拟基类,因此它的构造函数不会被最直接的派生类调用,这使得Move构造更加复杂。
这很有趣。看起来很奇怪。但它最终还是有效的。;-)
略微修正:
Alberto Ganesh Barbati在i/ostream
级别保护swap
的is responsible。对于他来说,这是一个非常好的决定,而我在第一次设计时完全忽略了这一点。
发布于 2011-11-16 15:35:58
我只有一个推测的答案...
如果作者假设流可以使用内部缓冲区(例如char buffer[50]
数据成员),那么这种规定是必要的,因为显然可以交换缓冲区的内容,但它们的地址将保持不变。
我不知道这是否真的被允许。
https://stackoverflow.com/questions/8147850
复制相似问题