我在以下简单代码中遇到问题:
void foo (vector<int>:: iterator it, vector<int> n)
{
vector<int>:: iterator it2 = it +1;
while (it2!=n.end())
{
cout<<*it2<<endl;
it2++;
}
}
main()
{
vector<int> m{1,2,3,4};
vector<int>:: iterator it = m.begin();
foo (it, m);
}
我希望在终端中有2,3和4,但我在输出中得到了一些愚蠢的结果。基本上可以使用迭代器作为函数&#39;输入?这段代码有什么问题?我怎样才能使它正确?
答案 0 :(得分:7)
您将vector<int> n
作为副本传递。因此,您的it2
指向不同的向量(在main
中创建的向量)。您的检查it2!=n.end()
无效,因为it2
是另一个向量的迭代器。
通过引用传递n
是一种解决方案。其他将通过结束迭代器而不是向量。
将矢量作为const引用传递:
void foo (vector<int>:: iterator it, const vector<int>& n)
传递结束迭代器:
void foo (vector<int>::iterator it, vector<int>::iterator end)
{
...
while ( it2 != end )
...
}
答案 1 :(得分:3)
你有两个问题:一个是你正在传递你的矢量参数的副本,正如Satus和yeputons已经指出的那样。
第二个问题是,如果参数为空,则foo
的第一行已经是非法的。也就是说,即使是微不足道的修复
void foo (vector<int>:: iterator it, vector<int> &n)
{
vector<int>:: iterator it2 = it +1;
如果it == n.end()
,则错误。
正确的设计是用于所有库算法的设计,并且出于同样的原因:它可以正确地表达空范围。
void foo (vector<int>::iterator begin, vector<int>::iterator end)
{
if (begin == end) return;
for (auto i = begin; i != end; ++i)
{
cout<<*i<<endl;
}
}
你的怪异跳过第一元素设计使它有点难看,一个更好的方法是让一些实用工具帮助跳过第一个元素,然后使用copy:
template <typename Iterator>
Iterator try_advance(Iterator i, int count, Iterator end)
{
for (; count-- > 0 && i != end; ++i)
;
return i;
}
void foo (vector<int>::iterator begin, vector<int>::iterator end)
{
// skip first element of a non-empty range
// leave an empty range un-damaged
begin = try_advance(begin, 1, end);
std::copy(begin, end, std::ostream_iterator<int>(std::cout, '\n'));
}
答案 2 :(得分:0)
是的,这是可能的。但请注意,迭代器与容器绑定。
您的函数的第二个参数是从参数复制构造的,即vector<int> n
是vector<int> m
中定义的main
的副本。因此,您的函数尝试将迭代器与来自不同容器的另一个迭代器(.end()
)进行比较。你最好传递开始/结束iteratos而不是容器。