为什么C++标准算法"count"会返回difference_type而不是size_t?

Sam*_*rsa 38 c++ std

为什么的返回类型std::countdifference_type迭代器(通常是的ptrdiff_t).

由于计数永远不会是负数,size_t 技术上不是正确的选择吗?如果计数超出ptrdiff_t阵列理论上可能的大小范围,该size_t怎么办?


编辑:到目前为止,没有合适的答案为什么函数返回ptrdiff_t.从下面的答案中得到的一些解释是返回类型iterator_traits<InputIterator>::difference_type是通用的,可以是任何东西.直到那时它才有意义.有些情况下,计数可能会超过size_t.但是,为什么返回类型是typedef ptrdiff_t iterator_traits<InputIterator>::difference_type标准迭代器而不是为什么仍然没有意义typedef size_t iterator_traits<InputIterator>::difference_type.

And*_*ron 14

std::count()算法依赖于迭代器类型来定义一个足以表示范围的任何大小的整数类型.容器的可能实现包括文件和网络流等.不能保证整个范围一次适合进程的地址空间,因此std::size_t可能太小.

由该标准提供的唯一的整体式std::iterator_traits<>std::iterator_traits<>::difference_type,其适用于两个迭代之间表示"距离".对于实现为(包装)指针的迭代器,这种类型是std::ptrdiff_t.size_type迭代器特征没有或类似,所以没有其他选择.


Ste*_*sop 8

size_t从技术上讲,这不是正确的选择,因为它可能不够大.允许迭代器迭代比内存中任何对象更大的"东西" - 例如磁盘上的文件.当它们这样做时,迭代器可以定义一个大于size_t它的类型difference_type(如果有的话).

difference_type需要进行签名,因为除了std::count它之外的上下文表示两个方向上的迭代器之间的偏移.对于随机访问迭代器,it + difference即使difference是负数也是一个非常明智的操作.

iterator_traits不提供无符号类型.也许它应该,但鉴于它不是iterator_traits<InputIterator>::difference_type最好的类型.

迭代器是否应该提供无符号类型的问题可能与编码样式的大量冲突有关,无论是否应使用无符号类型进行计数.我不打算在这里重现那个论点,你可以查一查.ptrdiff_t确实有一个弱点,在某些系统上它不能代表所有有效的指针差异,因此也不能代表所有预期的结果std::count.

据我所知,即使在C++ 03中,该标准实际上禁止了这一点,也许是偶然的.5.7/6谈论减法可能溢出ptrdiff_t,就像C一样.但表32(分配器要求)表示X::difference_type可以表示任何两个指针之间的差异,并std::allocator保证ptrdiff_t用作其difference_type(20.1.5/4).C++ 11是类似的.因此标准的一部分认为指针减法可能会溢出ptrdiff_t,而标准的另一部分则认为它不能.

std::count可能是在与分配器要求相同(可能有缺陷)的假设下设计的,它ptrdiff_t足以表达任何对象的大小,并且(通常)迭代器difference_type可以表示任意两个迭代器之间的迭代计数.


Mar*_*k B 5

返回类型typename iterator_traits<InputIterator>::difference_type在这种特定情况下恰好是ptrdiff_t.

推测difference_type是因为该范围内匹配元素的最大数量是迭代器差异last - first.

  • 问题是,只有在范围无效的情况下,差异才为负,并且在标准算法中使用这种无效范围是不确定的行为。 (2认同)
  • @R.Martinho Fernandes,`difference_type`显然能够在所有情况下包含完整的计数,但是`ptrdiff_t`不是 - 当指针大小只有32位时,考虑文件对象上的迭代器的情况. (2认同)
  • @ildjarn,__ far指针的存在不会自动排除保证,因为difference_type专门用于迭代器的类型. (2认同)

Mar*_*som -1

即使计数不能为负,返回类型也被指定为,iterator_traits<InputIterator>::difference_type并且两个迭代器之间的差可以为负。

  • 它没有回答问题,因为 `std::count` 不会返回*两个迭代器之间的差异*。 (7认同)
  • 这就引出了一个问题——为什么返回类型是 `std::iterator_traits&lt;InputIterator&gt;::difference_type` 而不是 `std::size_t`? (4认同)
  • @Nawaz:除了“std::iterator_traits&lt;&gt;::difference_type”之外,没有其他整数类型可以从迭代器类型推导出来。 (3认同)
  • @ildjarn,“difference_type”显然能够在所有情况下包含完整计数,但“size_t”则不能 - 考虑当指针大小仅为 32 位时文件对象上的迭代器的情况。 (2认同)