首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么`basic_ios::swap`只进行部分交换?

为什么`basic_ios::swap`只进行部分交换?
EN

Stack Overflow用户
提问于 2011-11-16 14:57:01
回答 2查看 463关注 0票数 18

C++11 §27.5.4.2/21:

void swap(basic_ios& rhs);

效果:*thisrhs的状态应该互换,只是rdbuf()返回的值与函数调用前的值相同,rhs.rdbuf()返回的值与函数调用前的值相同。

这种部分交换有什么用呢?

它会带来麻烦吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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_filebufbasic_stringbuf)的自引用指针,就是您不希望基类交换这些自引用指针的原因。

这使得基本swap很奇怪,但除了派生客户端之外,每个人都受到保护。随后,派生客户端的swap的代码看起来很简单。在派生级别,swap是公开的,并以公共客户端期望的方式运行。

类似的舞蹈也适用于移动构造和移动分配。由于基类是一个虚拟基类,因此它的构造函数不会被最直接的派生类调用,这使得Move构造更加复杂。

这很有趣。看起来很奇怪。但它最终还是有效的。;-)

略微修正:

Alberto Ganesh Barbati在i/ostream级别保护swapis responsible。对于他来说,这是一个非常好的决定,而我在第一次设计时完全忽略了这一点。

票数 21
EN

Stack Overflow用户

发布于 2011-11-16 15:35:58

我只有一个推测的答案...

如果作者假设流可以使用内部缓冲区(例如char buffer[50]数据成员),那么这种规定是必要的,因为显然可以交换缓冲区的内容,但它们的地址将保持不变。

我不知道这是否真的被允许。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8147850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档