我们可以在没有 'advance' 函数的情况下增加迭代器的多个位置吗?

Can we increase an iterator multiple positions without the 'advance' function?

我知道我们可以使用 advance() 函数来增加迭代器。我们还使用 iterator++ 将迭代器增加一个位置。为什么我们不能使用 it+=2?

int main()
{
    list<int> l1{1, 2, 3, 5, 6};
    list<int> l2{2, 6, 8};
    auto it = l1.begin();
    advance(it, 2);         //works
    it++;                   //works
    // it+=2;                  //not work
    l2.splice(l2.begin(), l1, it);

    for(int a: l2) cout<<a<<" ";
    cout<<endl;

    return 0;
}

你可以运行上面的代码here.

operator +=RandomAccessIterator 支持;请注意,它应该具有恒定的复杂性。

std::list is BidirectionalIterator的迭代器,不支持operator +=。 (std::vectorstd::array的迭代器是RandomAccessIterator。)

请注意,它们都可以与 std::advance 一起使用,当用于 RandomAccessIterator 时,复杂度是常数;当用于其他 InputIterators(包括 BidirectionalIterator)时,复杂度是线性的。这意味着使用 std::advance 是一个好主意,因为它更通用并且可以自动利用 RandomAccessIterator 的优势。

您不能将 += 2 与此迭代器一起使用,因为在一般情况下,将 std::list<> 迭代器递增任意值是相对 低效的 操作。 += 没有专门为您的迭代器类型定义,以防止您 carelessly/unknowingly 在代码中使用这种低效操作。相反,如果你真的想这样做,你应该使用 std::advance,这是一个 "red flag" 函数,旨在强调你可能正在做一些低效的事情。 std::advance 主要用于代码草图或 不太可能执行 后备代码。您不应该在生产代码中随意使用 std::advance 。如果你突然发现自己依赖 std::advance,这意味着你可能需要重新设计你的数据结构。基本上,std::advance 就像一个转换 - 除非你有非常非常好的理由使用它,否则请避免使用它。

或者,您可以使用 std::next

it = std::next(it, 2);

这个功能比std::advance好用多了。默认情况下,此函数旨在将迭代器向前推进 1 步,但您可以指定第二个参数以使其更远。同样,当第二个参数的值是非常量且可能很大时,应将其视为 "red flag" 函数。常数值 2 绝对在可接受的范围内。