【发布时间】:2010-11-06 15:36:46
【问题描述】:
谁能告诉我如何将迭代器增加 2?
iter++ 可用 - 我必须使用iter+2 吗?我怎样才能做到这一点?
【问题讨论】:
-
从答案的范围来看,您可能需要澄清您的问题。
-
是的。它是什么样的迭代器?显示一些代码。
标签: c++ visual-c++ stl iterator
谁能告诉我如何将迭代器增加 2?
iter++ 可用 - 我必须使用iter+2 吗?我怎样才能做到这一点?
【问题讨论】:
标签: c++ visual-c++ stl iterator
此方法适用于不是随机访问迭代器的迭代器,但当与随机访问迭代器一起使用时,它仍然可以通过实现进行专门化,使其效率不低于iter += 2。
【讨论】:
http://www.cplusplus.com/reference/std/iterator/advance/
std::advance(it,n);
在你的情况下,n 是 2。
这个函数的美妙之处在于,如果“it”是一个随机访问迭代器,那么速度很快
it += n
使用 操作(即 vector::iterator)。否则将其呈现为
for(int i = 0; i < n; i++)
++it;
(即列表<..>::iterator)
【讨论】:
【讨论】:
map<string,string>::iterator iter; for(iter = variations.begin(); iter != variations.end(); iter++) { map<string,string>::iterator it_tmp = std::next(iter, 1); // increment by 1 it_tmp = std::next(iter, 2); // increment by 2 } iter 会增加 2 吗?或 iter 只会影响 it_tmp?
您可以使用“加法赋值”运算符
iter += 2;
【讨论】:
我们可以同时使用std::advance 和std::next,但是两者之间是有区别的。
advance 修改其参数并且不返回任何内容。所以它可以用作:
vector<int> v;
v.push_back(1);
v.push_back(2);
auto itr = v.begin();
advance(itr, 1); //modifies the itr
cout << *itr<<endl //prints 2
next 返回迭代器的修改副本:
vector<int> v;
v.push_back(1);
v.push_back(2);
cout << *next(v.begin(), 1) << endl; //prints 2
【讨论】:
如果您不知道容器中是否有足够的下一个元素,则需要在每次增量之间检查容器的末尾。 ++ 和 std::advance 都不会为你做这件事。
if( ++iter == collection.end())
... // stop
if( ++iter == collection.end())
... // stop
您甚至可以推出自己的绑定安全高级功能。
如果你确定你不会越过终点,那么 std::advance(iter, 2 ) 是最好的解决方案。
【讨论】:
假设列表大小可能不是步骤的偶数倍,您必须防止溢出:
static constexpr auto step = 2;
// Guard against invalid initial iterator.
if (!list.empty())
{
for (auto it = list.begin(); /*nothing here*/; std::advance(it, step))
{
// do stuff...
// Guard against advance past end of iterator.
if (std::distance(it, list.end()) > step)
break;
}
}
根据集合实现,距离计算可能非常慢。以下是最佳且更具可读性。可以将闭包更改为实用模板,其中列表结束值由 const 引用传递:
const auto advance = [&](list_type::iterator& it, size_t step)
{
for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i);
};
static constexpr auto step = 2;
for (auto it = list.begin(); it != list.end(); advance(it, step))
{
// do stuff...
}
如果没有循环:
static constexpr auto step = 2;
auto it = list.begin();
if (step <= list.size())
{
std::advance(it, step);
}
【讨论】:
非常简单的答案:
++++iter
长答案:
你真的应该习惯写++iter 而不是iter++。后者必须返回(副本)旧值,这与新值不同;这需要时间和空间。
请注意,前缀增量 (++iter) 采用左值并返回左值,而后缀增量 (iter++) 采用左值并返回右值。
【讨论】:
iter 是原始指针(某些迭代器类型可以是),则行为未定义。 ++it; ++it; 很好。