从头到尾递增迭代器

Incrementing iterator from end to begin

我想遍历一个向量,当到达终点时它应该循环回到前面。

这是一个无法编译的小例子

#include <vector>

std::vector<int>::iterator Next(const std::vector<int>& vec, 
    const std::vector<int>::iterator it) 
{
    auto itNext = it+1;
    if (itNext == vec.end())
        itNext = vec.begin(); // breaks 
    return itNext;
}

int main()
{
    std::vector x{0, 2, 3, 4};
    auto it = x.begin()+1;        
    return *Next(x,it);
}

这里是 godbolt link.

问题的出现是因为 vector::const_iteratorbegin() 的结果)和 vector::iterator 之间没有可用的转换。 如何解决这个问题?

您不能将 const_iterator 转换为 iterator,因为这会破坏 const-correctness。

你基本上有两个选择。如果可以 return a const_iterator 然后 return a const_iterator:

#include <vector>

std::vector<int>::const_iterator Next(const std::vector<int>& vec, 
    std::vector<int>::const_iterator it) 
{
    auto itNext = it+1;
    if (itNext == vec.end())
        itNext = vec.begin();
    return itNext;
}

int main()
{
    std::vector x{0, 2, 3, 4};
    auto it = x.begin()+1;        
    return *Next(x,it);
}

您只能从 const std::vector& 得到一个 const_iterator。因此,如果你想 return 一个 iterator 向量必须作为 non-const 参考传递:

#include <vector>

std::vector<int>::iterator Next(std::vector<int>& vec, 
    std::vector<int>::iterator it) 
{
    auto itNext = it+1;
    if (itNext == vec.end())
        itNext = vec.begin(); 
    return itNext;
}

int main()
{
    std::vector x{0, 2, 3, 4};
    auto it = x.begin()+1;        
    return *Next(x,it);
}

为了将两者合而为一,我会传递迭代器并将函数作为模板,因此它可以与 iteratorconst_iterator 一起使用。该函数可能授予您 non-const 访问 vectors 元素的权限,但对于函数本身而言,迭代器是否为 const 并不重要。

#include <vector>


template <typename IT>
IT Next(IT it,IT begin,IT end) {
    auto itNext = it+1;
    return (itNext == end) ? begin : itNext;
}

int main()
{
    std::vector x{0, 2, 3, 4};
    auto it = x.begin()+1;        
    auto it2 = Next(it,x.begin(),x.end());
    *it2 = 42;
}