必须size()== end() - begin()?演员怎么样?

时间:2012-07-26 00:37:57

标签: c++ iterator language-lawyer

根据我的理解,size_typedifference_type的目的是而不是仅仅是标志 - 它也意味着要解决,例如分段架构等,它们可能有不同的大小。

使用该上下文,如果我有一个具有随机访问迭代器的容器,我可以安全地在其static_castdifference_type值之间执行size_type, {2}

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

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

2 个答案:

答案 0 :(得分:12)

以下是C++11 standard在各种事情上所说的内容:

§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_typesize_type的演员表对所有非负值都有效。

答案 1 :(得分:2)

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

的规范

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

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

P.S。我要说difference_type存在的原因只是标志而已。要完全“安全”difference_type应该比size_type长1位。这在实践中通常很难实现,这就是语言规范不要求的原因。