我正在编写自定义算法,并且在某些时候需要获得两个迭代器之间的距离。如果我假设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
,但我无法确定先前未定义的行为是否像我假设的那样有效。我该如何处理这个问题?
答案 0 :(得分:2)
[..]如果距离太大而不适合[
distance_type
]但会适合[某些其他类型] [...]我该如何处理这个问题?
你做不到。无论是谁实现了容器以及相应的迭代器,都是它的工作。
如果他们用于距离的类型不能适应容器可能出现的所有值,那么这就是容器中的错误。
澄清:difference_type
实际使用了depends on the iterators。
答案 1 :(得分:1)
这永远不会成为问题。我们知道这是因为max_size
以size_t
表示。 max_size
的返回代表:
string
由于系统或库实施限制而能够容纳的最大元素数,即最大字符串的std::distance(begin(), end())
因此,string
的迭代器不能超过size_t
。
答案 2 :(得分:0)
关于如何处理问题的可能实现。
让我们把它留给类型演绎系统来进行正确的调用。
预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
}