为什么`basic_ios :: swap`只做部分交换? [英] Why does `basic_ios::swap` only do a partial swap?

查看:215
本文介绍了为什么`basic_ios :: swap`只做部分交换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


C ++ 11 §27.5.4.2/ 21:

swap(basic_ios& rhs);

效果: / code>和 rhs 将被交换,除了 rdbuf()在函数调用之前返回相同的值, rhs.rdbuf()将返回与函数调用之前返回的值相同的值。

Effects: The states of *this and rhs shall be exchanged, except that rdbuf() shall return the same value as it returned before the function call, and rhs.rdbuf() shall return the same value as it returned before the function call.

这个部分交换对什么有用?

What is this partial swapping useful for?

它会引起麻烦吗?

推荐答案

你可以怪我这个。

交换和移动语义被改进到我们的I / O系统上十年后设计。

Swap and move semantics was retrofitted onto our I/O system a decade after it was designed. And it wasn't a perfectly clean fit.

请注意, basic_ios :: swap 是一个受保护的成员函数,并且没有命名空间范围变量。因此,这只能从派生类(通常istream / ostream)中调用。请注意, i / o_stream :: swap 也受保护,没有命名空间范围变量。他们的规范是调用基类 swap ,然后交换任何本地数据(例如 gcount istream )。

Note that basic_ios::swap is a protected member function and there is no namespace-scope variant. Thus this can only be called from a derived class (typically istream/ostream). Note that i/o_stream::swap is also protected and with no namespace-scope variant. And their spec is to call the base class swap and then swap any local data (such as the gcount in istream).

最后在 string / filestream 你会得到你会认为一个正常 swap :public成员和命名空间范围变体。在这个级别你有一个数据成员 string / file buffer rdbuf )和基类。 swap 在此级别只是交换基础和数据成员。

Finally up at the string/filestream level you get what you would consider a "normal" swap: public member and namespace-scope variants. At this level you've got a data member string/file buffer (the rdbuf) and the base class. The swap at this level simply swaps the base and data members.

这一切的复杂特性是 rdbuf()下面的基类实际上是一个自引用指向派生类的 streambuf $ c> basic_filebuf basic_stringbuf )和是为什么你不想让基类交换这些自我 -

The complicating characteristic of all this is that the rdbuf() down in the base class is actually a self-referencing pointer to the derived class's streambuf (basic_filebuf or basic_stringbuf) and that is why you don't want the base class to swap these self-referencing pointers.

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

This makes the base swap weird, but everyone is protected from it except the derived clients. And the code for the derived client's swap is subsequently deceptively simple looking. And at the derived level, swap is made public and behaves in the manner that public clients expect it to.

类似的舞蹈是为移动建设和移动任务。由于基类是一个虚拟基础,因此它的构造函数不是由最直接的派生类调用,因此移动构建进一步复杂化。

A similar dance is made for move construction and move assignment. Move construction is further complicated by the fact that the base class is a virtual base, and thus its constructor is not called by the most directly derived class.

这很有趣。看起来很奇怪。但它最终工作。 ; - )

It was fun. It looks weird. But it ultimately works. ;-)

稍微更正

Alberto Ganesh Barbati 负责保护交换 i / ostream 级别。这是一个非常好的电话,他的部分,我完全错过了我的第一个设计。

Alberto Ganesh Barbati is responsible for protecting swap at the i/ostream level. It was a very good call on his part that I had completely missed with my first design.

这篇关于为什么`basic_ios :: swap`只做部分交换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆