Bizzare std::distance output

Bizzare std::distance output

本文关键字:output distance Bizzare std      更新时间:2023-10-16

我直接从我正在处理的一些代码中取出了这个小片段:

KeyIter it = timeline_.lowerBound( frame );
if ( timeline_.isKeyAtFrame( frame ) ) {
    ++it;
}
KeyIter it1 = it - 1;
cout << "dist1: " << std::distance( timeline_.begin(), it1 ) << endl;
while ( ignore.contains( it1.key() ) ) {
    cout << "dist2: " << std::distance( timeline_.begin(), it1 - 1 ) << endl;
    if ( std::distance( timeline_.begin(), --it1 ) < 0 ) {
        break;
    }
}
cout << "dist3: " << std::distance( timeline_.begin(), it1 ) << endl;

它给出以下输出:

dist1: 0
dist2: 2
dist3: 2

ignore 是一个QSet<int>it1timeline_ 的迭代器(它是键为 int 的映射类型)。 如您所见it1从开头开始(这是正确的),然后控制进入 while 循环,其中迭代器向后移动一个;但 std::d istance 不是 -1,而是 2! 中间发生的所有事情都是使用密钥的副本来检查QSet是否包含相同的int

使用调试器,我可以确认timeline_在两个dist#输出之间不会更改(无论如何,此时代码中只有一个线程正在运行)。

谁能明白为什么std::distance会给出这个输出?

我不确定Qt在这方面的行为,但在标准库容器中,获取范围之外的迭代器[container.begin(),container.end()]是未定义的行为。 我认为在Qt中也是如此,尽管我不确定。 但是,即使不是,非随机访问迭代器上的std::distance行为也是计算从第一个迭代器到最后一个迭代器所需的增量数,因此:

std::distance(x,y)

其中yx之前,是未定义的行为。