我知道我们可以使用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。
答案 0 :(得分:29)
operator +=
仅受RandomAccessIterator支持;请注意,它应该具有恒定的复杂性。
std::list
的迭代器是BidirectionalIterator,它不支持operator +=
。 (std::vector
和std::array
的迭代器是RandomAccessIterator。)
请注意,当用于RandomAccessIterator的复杂性是恒定的时,它们都可以与std::advance一起使用;当用于其他InputIterators(包括BidirectionalIterator)时,复杂度是线性的。这意味着使用std::advance
是个好主意,因为它更通用,可以自动利用RandomAccessIterator的优势。
答案 1 :(得分:15)
您不能将此迭代器与+= 2
一起使用,因为通常情况下,将std::list<>
迭代器递增任意值是相对 invalid 的操作。未为您的迭代器类型定义+=
,专门用于防止您不小心/不知不觉地在代码中使用此低效操作。相反,如果您确实想这样做,则应该使用std::advance
,这是一个“红色标志”函数,旨在强调您可能在做效率低下的事情。 std::advance
主要用于代码草绘或不太可能执行的后备代码。您不应在生产代码中随意使用std::advance
。如果您突然发现自己依赖std::advance
,则意味着您可能需要重新设计数据结构。基本上,std::advance
就像演员一样-除非有非常非常好的理由使用它,否则请避免使用它。
或者,您可以使用std::next
it = std::next(it, 2);
此功能比std::advance
易于使用。默认情况下,此函数旨在使迭代器前进1步,但是您可以指定第二个参数将其进一步移动。同样,当第二个参数的值不是恒定的并且可能很大时,应将其视为“红色标志”函数。常数2肯定在可接受的范围内。