标题几乎说明了一切。
我正在实施自己的streambuf课程,我想知道委员会在决定同时包括std::streambuf::seekpos()
和std::streambuf::seekoff()
时的想法(以及相关的pubseekpos()
和{ {1}})。
在我看来,pubseekoff()
在我能想象的每种情况下都应该与seekpos(x)
具有相同的效果。但也许我的想象力不够好。那么,为什么在seekoff(x, std::ios::beg)
完全归入seekpos
时你想要同时拥有两者?或者至少,为什么不让前者的默认实现只调用后者?
如果答案是"因为那就是STL所做的"或类似的,然后假设我询问STL或类似的理由。
(我意识到seekoff
的第一个参数是seekpos
而streampos
的第一个参数是seekoff
。但请注意27.4.3.2 [lib。 fpos.operations]要求流位置可以转换为流偏移并返回,所以我认为这不是答案。)
答案 0 :(得分:13)
这两个函数使用不同的参数:
你是完全正确的:他们可以双向转换。但是有一个微妙的语义差异:
streampos
直观地与固定位置相关,而streamoff
在某种程度上与文件中的运动相关。 streampos
中扣除一个streampos
会产生streamoff
。 streampos
添加streamoff
会新增streampos
。wstreampos
作为位置(因为wchar_t
中的位置显然与char
流中的位置具有不同的含义。 streamoff
进行动作,因为它是与位置相比的相对运动。如果您使用模板编程,这些语义差异对于特征S::pos_type
和S::off_type
更明确。
无论这些语义潜意识如何,这种差异的真正起源都是历史性的,与 C标准库有关,正如Plauger先生在this article中所解释的那样:
我可以验证这是C89标准中的情况。由于原始K& R中没有提到这些功能,因此UNIX历史学家可能会更多地了解更远的路径。
This paper解释了标准委员会最近的想法。似乎历史性的差异受到了质疑,现在还不再清楚是否真的需要它。
答案 1 :(得分:2)
我想知道委员会在决定同时包括std :: streambuf :: seekpos()和std :: streambuf :: seekoff()时的想法(同样对于相关的pubseekpos()和pubseekoff())
streampos
表示从流开始的绝对位置。因此,seekpos()
寻求特定的位置。
streamoff
表示距离给定位置的偏移量。因此,seekoff()
可以相对于任何给定的位置寻求。这就是为什么它有dir
参数来指定如何解释偏移量 - 从流的开头/结尾开始的偏移量,或相对于流的当前位置的偏移量。
不同的语义,所提供的功能不同。
在我看来,在我能想象的每种情况下,seekpos(x)应该与seekoff(x,std :: ios :: beg)具有相同的效果。
这在逻辑上是什么,是的。虽然可以优化实际实现,例如通过考虑当前位置来最小化所涉及的物理搜索量,尤其是对于文件流。要让操作系统一直回到文件的开头再向前移动并不总是有效的。
那么,为什么当搜索引擎完全被搜索包含时,你想要两者兼顾?
因为有时直接寻找特定位置是有意义的,有时寻求相对偏移是有意义的。这取决于具体情况。这两种情况都有其用途。
那么,为什么当搜索引擎完全被搜索包含时,你想要两者兼得?
便利。取决于调用代码的设计,无论是跟踪绝对位置还是相对偏移。
或者至少,为什么不让前者的默认实现只调用后者?
可能是。它是实现定义的。
但请注意,27.4.3.2 [lib.fpos.operations]要求流位置可以转换为流偏移并返回,所以我认为这不是答案。)
Convertible 是这里的关键词。仅仅因为它们可以转换彼此并不意味着它们在语义上相等彼此。