size_type 中迭代器之间的长度
Posted
技术标签:
【中文标题】size_type 中迭代器之间的长度【英文标题】:Length between iterators in size_type 【发布时间】:2018-09-11 14:40:15 【问题描述】:我正在编写自定义算法,在某些时候它需要获取两个迭代器之间的距离。如果我假设 it1
it2 我可以得到它们之间的正距离(it2 - it1
)。这没关系,但是std::distance
和operator-
返回difference_type
(在我的情况下)是long long
的别名。如果距离太大而无法放入long long
但可以放入unsigned long long
(在我的情况下是size_type
别名)怎么办?
对于这个例子,我还假设long long
是int64_t
和unsigned long long
是uint64_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
数据类型的容量,以及签名数据类型的灵活性,我建议您创建自己的新类型。一种新类型,它将是一对 <bool, unsigned>
。如果您愿意,我可以绘制一个适用于新数据类型的示例应用程序。 bool
将存储符号信息,而 unsigned
部分将存储幅度。【参考方案3】:
这永远不会成为问题。我们知道这一点是因为max_size
表示为size_t
。 max_size
的返回代表:
由于系统或库实现限制,
string
能够容纳的最大元素数,即std::distance(begin(), end())
表示最大字符串
因此,无法使用大于size_t
分隔的string
的迭代器。
【讨论】:
以上是关于size_type 中迭代器之间的长度的主要内容,如果未能解决你的问题,请参考以下文章
为什么迭代器只能被一个集合使用呢 为什么迭代器不能在迭代过程中 ?增删呢 是因为 每次迭代时候 把之前的元素给拿出去了 如果你在操作过程中将下一个迭代元素给拿走了(迭代器不具备自动判断长度功能 她依旧