size_type 中迭代器之间的长度

Length between iterators in size_type

我正在编写自定义算法,有时它需要获取两个迭代器之间的距离。如果我假设 it1 < it2 我可以获得它们之间的正距离 (it2 - it1)。这没关系,但是 std::distanceoperator- returns difference_type (在我的例子中)是 long long 的别名。如果距离太大而不适合 long long 但适合 unsigned long long 怎么办(在我的例子中是 size_type 别名)? 对于这个例子,我还假设 long longint64_t 并且 unsigned long longuint64_t:

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

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

[..] What if the distance is too big to fit in [distance_type] but will fit inside [some other type] [..]

How can I deal with such issue?

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

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

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

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

让我们把它留给 type-deduction 系统来做出正确的调用。

Pre 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());
}

Post 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
}

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

The maximum number of elements the string is able to hold due to system or library implementation limitations, i.e. ​std::distance(begin(), end())​ for the largest string

因此 string 的迭代器不可能被大于 size_t 分隔。