可能可以使用rdbuf和copyfmt创建iostream对象的本地副本。这使得格式化更改可以在本地范围内进行:
std::ostream & operator << ( std::ostream & os, foo const & smth ) {
cloned_ostream cs( os );
cs << std::hex << smth.num;
// os is not switched to hexadecimal, which would be a confusing side-effect
return os;
}为什么流类不提供副本构造函数来完成这个任务呢?
相关的C++最佳实践是否已经改变,因为它们被设计为不可复制?
发布于 2016-03-17 06:34:25
复制和移动是价值语义操作.要定义它们,首先必须确定类的哪些属性为其对象提供了不同的值。最初,对于iostreams库来说,这一点基本上被回避了,然后C++11采取了与这样一个复制构造函数不兼容的不同方向。
流对象的状态包括两个部分:指向具有关联状态的流缓冲区的指针和格式化信息。因为C++98、rdbuf、rdstate和copyfmt分别公开了这些信息。
由于C++11,流类还具有一个protected接口,其中包括一个移动构造函数(以及一个名为move的成员),该构造函数复制格式,但不复制流缓冲区指针。这就提交了iostream来将格式化信息单独处理为流对象的状态。
如果此时流是可复制的,那么它将只执行copyfmt,而不执行其余的操作。
将rdbuf从值状态中排除出来的选择可能是由于派生类(如std::fstream )的值语义更加混乱,它不仅公开对流缓冲区的访问,而且嵌入和拥有它。
std::ifstream f( path + filename ); // Owns, or even "is," a file.
std::istream i = f; // Observes an externally-managed file.
std::istream i2 = i; // OK, copy a shallow reference.
std::ifstream f2 = f; // Error, ifstream is more than a shallow reference.
std::istream i3 = std::move( f ); // Error? Would retain a reference to an rvalue.
std::ifstream f3 = std::move( f ); // OK: full copy including the file buffer.语义可能在某种程度上是一致的,但对于一个适度的收益来说,这将是一个很大的混乱。
https://stackoverflow.com/questions/36051672
复制相似问题