从头到尾递增迭代器
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_iterator
(begin()
的结果)和 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);
}
为了将两者合而为一,我会传递迭代器并将函数作为模板,因此它可以与 iterator
或 const_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;
}
我想遍历一个向量,当到达终点时它应该循环回到前面。
这是一个无法编译的小例子
#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_iterator
(begin()
的结果)和 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);
}
为了将两者合而为一,我会传递迭代器并将函数作为模板,因此它可以与 iterator
或 const_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;
}