20

据我了解,size_typeanddifference_type的目的不仅仅是标志 - 它还旨在解决例如分段架构等,它们可能具有不同的大小。

在这种情况下,如果我有一个带有随机访问迭代器的容器,我是否可以随意在它的和值static_cast之间执行 a ,因为当任何一个被强制转换时,它必须始终等于? difference_typesize_typeend() - begin() size()

(例如,用例是创建一个容器,其大小等于两个迭代器之间的元素数量,或者相反:将某个大小的容器复制到由迭代器分隔的范围内。)

在投射之前我应该​​注意什么(例如数据丢失)?

4

2 回答 2

13

以下是C++11 标准在这里对各种事情的看法:

§ 23.2.1

Expression: difference_type
Return Type: signed integer type
Operational Semantics: -
Assertion/note, pre-/post-condition: is identical to the difference type of iterator and const_iterator
Complexity: compile-time

Expression: size_type
Return Type: unsigned integer type
Operational Semantics: -
Assertion/note, pre-/post-condition: size_type can represent any non-negative value of difference_type
Complexity: compile-time

Expression: size()
Return Type: size_type
Operational Semantics: distance(begin(),end()) 
Assertion/note, pre-/post-condition: -
Complexity: constant

让我们确保size()等效于end() - begin()

§ 24.4.4/4

distance():
Effects: If InputIterator meets the requirements of random access iterator, 
returns (last - first); otherwise, returns the number of increments needed 
to get from first to last

由于您的容器具有随机访问迭代器,因此这是正确的。就是这样。正如您在第一个框中看到的,

size_type can represent any non-negative value of difference_type

由此,我们认为从difference_typeto的转换size_type应该对所有非负值都有效。

于 2012-07-26T01:05:05.433 回答
2

我不认为它总是安全的。这个历史问题自 C 语言首次规范以来就存在,ptrdiff_t不能保证涵盖size_t. 由于显而易见的原因,这个问题延续到std::vector.

使用标准 C++ 容器,可以保证size_type覆盖 的非负范围difference_type,但不能保证反向覆盖。

但是,可以通过其他方式来保证标准容器size()之间的关系。实现可以自由地对通过函数end() - begin()公开的最大容器大小施加自己的限制。container::max_size()它可以人为地限制最大大小以确保减法永远不会溢出。

PS我想说difference_type' 存在的原因只是符号,没有别的。为了完全“安全” difference_type,应该比size_type. 这在实践中通常很难实现,这就是语言规范不要求它的原因。

于 2012-07-26T00:50:31.737 回答