📜  C++中的std :: next vs std :: advance(1)

📅  最后修改于: 2023-12-03 15:29:54.012000             🧑  作者: Mango

C++中的std::next vs std::advance

在C++标准库中,有两个函数可以用来在容器中移动迭代器:std::nextstd::advance。它们本质上是相似的,但它们的使用场景和实现略有不同。在本篇文章中,我们将详细介绍这两个函数。

std::next

std::next函数的声明如下:

template< class ForwardIt >
constexpr ForwardIt next( ForwardIt it, typename std::iterator_traits<ForwardIt>::difference_type n = 1 );

它接受一个迭代器 it 和一个整数 n,并返回迭代器指向第 n 个元素的迭代器。如果不传入 n,则默认为1。如果迭代器已经指向容器的end()位置,那么无论 n 的值如何,返回的迭代器都会是end()。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6};
    
    auto it = v.begin(); // it指向第一个元素
    std::cout << *it << std::endl; // 输出1
    
    auto it2 = std::next(it, 3); // it2指向第四个元素
    
    std::cout << *it2 << std::endl; // 输出4
}

如上代码,std::next函数将返回it加上3个元素后的迭代器,所以输出4。

std::advance

std::advance函数的声明如下:

template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );

它接受一个迭代器 it 和一个整数 n,并以传入的迭代器为准,将 it 移动 n 个元素的距离。如果 n 是负数,则向前移动;如果是正数,则往后移动。如果 n 的绝对值大于当前迭代器位置到容器end()的距离,则将迭代器移动到end()的位置。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6};
    auto it = v.begin();
    
    std::advance(it, 3); // 将it移动3个元素
    
    std::cout << *it << std::endl; // 输出4
    
    std::advance(it, -2); // 将it向前移动2个元素
    
    std::cout << *it << std::endl; // 输出2
}

如上代码,std::advance函数移动迭代器的方式与std::next函数类似,但它会直接修改迭代器,因此需要传入一个迭代器的引用。

总结

虽然 std::nextstd::advance 函数可以用来在容器中移动迭代器,但在实际编程中,建议根据使用场景选择其中的一个。例如如果只是想获取一个迭代器指向某个位置,而不需要修改原始迭代器,则使用 std::next 更为合适;而如果要修改原始迭代器的位置,则使用 std::advance 更为方便。