size_type 中迭代器之间的长度

Posted

技术标签:

【中文标题】size_type 中迭代器之间的长度【英文标题】:Length between iterators in size_type 【发布时间】:2018-09-11 14:40:15 【问题描述】:

我正在编写自定义算法,在某些时候它需要获取两个迭代器之间的距离。如果我假设 it1 it2 我可以得到它们之间的正距离(it2 - it1)。这没关系,但是std::distanceoperator- 返回difference_type(在我的情况下)是long long 的别名。如果距离太大而无法放入long long 但可以放入unsigned long long(在我的情况下是size_type 别名)怎么办? 对于这个例子,我还假设long longint64_tunsigned long longuint64_t

std::string container = ...; // assume enourmous number of characters, like 2^64 - 1024
std::cout << (container.begin() - container.end());

由于operator- 返回difference_type,它不适合2^64 - 1024,由于溢出,它应该打印负数(实际上是任何东西-它是UB)。当然,我可以将其转换回std::string::size_type,但我不能确定以前的未定义行为是否像我假设的那样有效。我该如何处理这样的问题?

【问题讨论】:

您不能将距离存储在difference_type 类型的变量中吗?我的意思是您可以使用基于模板的解决方案来涵盖所有情况。 在我不那么谦虚的意见中,如果你有这么大的数据集,你需要一个无符号的 64 位整数来表示两个元素之间的“距离”,那么你使用了错误的数据结构或错误的设计。 并不是我会有这么多数据。我只想知道可能的解决方案是什么。我不希望我的算法在“大多数情况下”起作用。我可以使用转换保留它,但数据溢出是可行的:/ 2^64 内存的成本是多少,您的任何客户能否将其专用于您程序中的单个容器? 这个问题真的很简单,如果你有C++11编译器的话。只需使用auto :) 【参考方案1】:

[..] 如果距离太大而无法放入 [distance_type] 但可以放入 [其他类型] [..]

我该如何处理这样的问题?

你不能。这是实现容器以及相应迭代器的人的工作。

如果他们用于距离的类型不能适合容器可能出现的所有值,那么这是容器中的错误。

澄清:difference_type 实际上是使用了depends on the iterators。

【讨论】:

【参考方案2】:

关于我将如何解决问题的可能实现。

让我们把它留给类型推断系统来做出正确的调用。

C++11 前的实现 -

template<typename It>
void distance_algo_impl(It const & begin, It const & end)

    typename std::iterator_traits<It>::difference_type distance
        = std::distance(begin, end);

    std::cout << "\ndistance :" << distance << "\n";
    // ... do your distance based algorithm here


template<typename T>
void distance_algo(T const & container)

    distance_algo_impl(container.begin(), container.end());

后 C++11 实现 -

template<typename T>
void distance_algo(T const & container)

    auto distance = std::distance(container.begin(), container.end());
    std::cout << "\ndistance :" << distance << "\n";
    // ... do your distance based algorithm here

【讨论】:

这不是我想要的。我知道类型推导可以“起作用”,但这并不能解决转换有符号->无符号的问题。 嗯,我不清楚你想要什么。如果您需要unsigned 数据类型的容量,以及签名数据类型的灵活性,我建议您创建自己的新类型。一种新类型,它将是一对 &lt;bool, unsigned&gt; 。如果您愿意,我可以绘制一个适用于新数据类型的示例应用程序。 bool 将存储符号信息,而 unsigned 部分将存储幅度。【参考方案3】:

这永远不会成为问题。我们知道这一点是因为max_size 表示为size_tmax_size的返回代表:

由于系统或库实现限制,string 能够容纳的最大元素数,即std::distance(begin(), end()) 表示最大字符串

因此,无法使用大于size_t 分隔的string 的迭代器。

【讨论】:

以上是关于size_type 中迭代器之间的长度的主要内容,如果未能解决你的问题,请参考以下文章

为什么迭代器只能被一个集合使用呢 为什么迭代器不能在迭代过程中 ?增删呢 是因为 每次迭代时候 把之前的元素给拿出去了 如果你在操作过程中将下一个迭代元素给拿走了(迭代器不具备自动判断长度功能 她依旧

映射不同长度的迭代器

迭代器

迭代器

List分组迭代器

迭代器模块 itertools